Arhn - архитектура программирования

PL/SQL ORA-01422 Ошибка для SELECT INTO, анонимный блок Oracle (среда NOVA)

Получение следующей ошибки: ORA-01422: точная выборка возвращает больше запрошенного количества строк ORA-6512

Новичок в PL/SQL, и хотя я ЗНАЮ, что этот запрос должен выполняться через стандартный SQL, я пытаюсь понять, как это сделать с помощью PL/SQL.

Мне нужен запрос, чтобы вернуть общее количество ПРОДАЖ для клиентов с почтовым индексом "20636"

Вот таблицы/ввод:

CREATE TABLE CUSTOMERS
(customerID     INT     PRIMARY KEY,
customerZip     VARCHAR(15) NOT NULL); 

CREATE TABLE SALES
(saleID         INT     PRIMARY KEY,
customerID      INT,
CONSTRAINT SALES_FK1 FOREIGN KEY (customerID) REFERENCES CUSTOMERS(customerID));

INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (1, '20636');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (2, '20619');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (3, '20650');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (4, '20670');
INSERT INTO CUSTOMERS (customerID, customerZIP) VALUES (5, '20636');

INSERT INTO SALES (saleID, customerID) VALUES (1, 1);
INSERT INTO SALES (saleID, customerID) VALUES (2, 2);
INSERT INTO SALES (saleID, customerID) VALUES (3, 3);
INSERT INTO SALES (saleID, customerID) VALUES (4, 4);
INSERT INTO SALES (saleID, customerID) VALUES (5, 5);

Вот код, который я написал для анонимного блока PL/SQL:

DECLARE
customerZip INTEGER;
totalSales INTEGER;
BEGIN
SELECT customerID INTO customerZip from CUSTOMERS where customerZip = '20636';
SELECT COUNT(*) INTO totalSales from SALES where customerID = customerZip;
DBMS_OUTPUT.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || customerZip ||'.');
END;
/

Если я запускаю это без двух атрибутов customerZIP, установленных на «20636», все работает нормально. Как только я ввожу более одной записи клиента с почтовым индексом «20636», я получаю сообщение об ошибке.

Не могли бы вы объяснить, что я делаю неправильно здесь и как я могу это исправить? Благодарю вас!

Ссылка на SQL Fiddle, если это поможет: http://sqlfiddle.com/#!4/10fc1


  • Это: SELECT customerID INTO customerZip... возвращает более 1 идентификатора клиента. Чтобы исправить это, вы можете массово собрать в какую-нибудь коллекцию или использовать аналитику, например row_number, чтобы выбрать только 1 идентификатор клиента. 07.02.2018
  • Именно так, потому что два идентификатора клиента (1 и 5), основанные на предоставленных мной данных, имеют почтовый индекс 20636. Как я могу изменить код, чтобы он выбирал несколько идентификаторов клиентов? Другими словами, поскольку в 20636 проживает несколько клиентов из моей таблицы, необходимо будет учитывать каждого из них. Я предполагаю, что это своего рода петля? 07.02.2018
  • Вы можете превратить этот выбор в курсор и прокрутить их (или использовать коллекцию, например вложенные таблицы). Или, в этом случае, просто выполните запрос GROUP BY (выберите zip, sum(что угодно), count(*) из my_table, где... group by zip) 07.02.2018

Ответы:


1

Вы можете использовать такое утверждение:

SQL> set serveroutput on;
SQL> DECLARE
  v_customerZip CUSTOMERS.customerZip%type:='20636';
  v_customerID  CUSTOMERS.customerID%type;
  totalSales    INTEGER:=0;
  Sales         INTEGER;
BEGIN
 for c in ( SELECT customerID from CUSTOMERS where customerZip = v_customerZip )
 loop
  v_customerID := c.customerID;
  SELECT COUNT(1) INTO Sales from SALES where customerID = v_customerID;
  totalSales := totalSales + Sales;
 end loop; 
  dbms_output.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || v_customerZip ||'.');
END;
/
We sold 2 Cars to customers in Zip Code 20636.

и измените значение переменной v_customerZip на то, что вы хотите, в части объявления.

Или вы можете создать процедуру для выполнения этой задачи:

SQL> CREATE OR REPLACE PROCEDURE GET_SALES( v_customerZip CUSTOMERS.customerZip%type ) IS
  v_customerID  CUSTOMERS.customerID%type;
  totalSales    INTEGER:=0;
  Sales         INTEGER;
BEGIN
 for c in ( SELECT customerID from CUSTOMERS where customerZip = v_customerZip )
 loop
  v_customerID := c.customerID;
  SELECT COUNT(1) INTO Sales from SALES where customerID = v_customerID;
  totalSales := totalSales + Sales;
 end loop; 
  dbms_output.put_line('We sold ' || totalSales || ' Cars to customers in Zip Code ' || v_customerZip ||'.');
END;
/
SQL> exec get_sales('&cZ');
Enter value for cz: 20636
We sold 2 Cars to customers in Zip Code 20636.
07.02.2018
  • Сделал трюк. Спасибо! Отличная информация... надеюсь, она начнет приходить мне в голову... SQL проще по сравнению с PL/SQL. 08.02.2018
  • Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..