#oracle #plsql
Вопрос:
DECLARE
c_id c_customer.customer_name%type;
coin_id1 i_invoice.coin_id%type;
coin_price c_coin.price%type;
delivery i_invoice.delivery_date%type;
CURSOR i_invoice ,c_coin ,c_customer is
SELECT customer_name, coin_id, price ,delivery_date
FROM ((invoice
INNER JOIN customer on invoice.customer_id = customer.customer_id)
INNER JOIN coin on invoice coin_id = coin.coin_id)
WHERE delivery_date BETWEEN '18 MAY 2021' AND '20 MAY 2021'
BEGIN
OPEN i_invoice,c_customer,c_coin;
LOOP
FETCH c_customers into customer_id ,
c_coin into coin_id,
c_coin into price,
i_invoice into delivery_date;
EXIT WHEN i_invloice%notfound;
dbms_output.put_line(customer_id || ' ' || coin_id || ' '
|| price || ' ' || delivery_date);
END LOOP;
CLOSE i_invoice;
END;
/
Комментарии:
1. В чем заключается ошибка, которую вы получаете? Хотя ваше объявление курсора неверно.
2. Один из возможных источников ошибок: сравнение
delivery_date
со строками . Вы должны преобразовать их в даты:to_date('18 MAY 2021', 'dd MON yyyy')
. Очень распространенная ошибка новичка (но тоже очень дорогая).3. ошибка возникает при объявлении курсора
4. кто-нибудь, пожалуйста, может исправить мою декларацию курсора?
Ответ №1:
Ты устроил довольно большой беспорядок. Позвольте мне попробовать выбрать некоторые ошибки:
- в
declare
разделе вы используете одни имена таблиц (i_invoice
,c_coin
), в то времяfrom
как предложение курсора предполагает другие (invoice
,coin
) - например, курсор должен иметь имя
c1
. Его имени не может бытьi_invoice ,c_coin ,c_customer
. Вы бы на самом деле ввели курсор в эти переменные where
предложение неверно — еслиdelivery_date
тип данных столбцаdate
(я предполагаю, что это так, как и должно быть), то не сравнивайте его со строками.'18 MAY 2021'
это струна. Литерал даты (я использовал) не являетсяopen
это так же неправильно, как объявление курсора; вы быopen c1
fetch
также потерпел бы неудачу, посколькуcustomer_id
в егоselect
списке столбцов нет. Кроме того, почему вы лезетеc_coin
в обаcoin_id
иprice
?
Я бы посоветовал вам for
вместо этого использовать цикл курсора. Вам не нужно явно объявлять какие-либо переменные, открывать курсор, извлекать переменные, заботиться о выходе из цикла или закрытии курсора. Что-то вроде этого (с фиктивными таблицами, которые я создал, просто чтобы показать, что код компилируется):
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
Описание:
SQL> desc customer
Name Null? Type
----------------------------------------- -------- ----------------------------
CUSTOMER_NAME VARCHAR2(10)
CUSTOMER_ID NUMBER
SQL> desc invoice
Name Null? Type
----------------------------------------- -------- ----------------------------
COIN_ID NUMBER
DELIVERY_DATE DATE
CUSTOMER_ID NUMBER
SQL> desc coin
Name Null? Type
----------------------------------------- -------- ----------------------------
PRICE NUMBER
COIN_ID NUMBER
Содержание:
SQL> select * from customer;
CUSTOMER_N CUSTOMER_ID
---------- -----------
Littlefoot 1
SQL> select * from invoice;
COIN_ID DELIVERY_D CUSTOMER_ID
---------- ---------- -----------
1 19.05.2021 1
SQL> select * from coin;
PRICE COIN_ID
---------- ----------
100 1
Сам код:
SQL> set serveroutput on
SQL> begin
2 for cur_r in (select t.customer_id,
3 t.customer_name,
4 c.coin_id,
5 c.price,
6 i.delivery_date
7 from invoice i join customer t on i.customer_id = t.customer_id
8 join coin c on i.coin_id = c.coin_id
9 where i.delivery_date between date '2021-05-18' and date '2021-05-20'
10 )
11 loop
12 dbms_output.put_line(cur_r.customer_id
13 || ' '
14 || cur_r.coin_id
15 || ' '
16 || cur_r.price
17 || ' '
18 || cur_r.delivery_date);
19 end loop;
20 end;
21 /
1 1 100 19.05.2021
PL/SQL procedure successfully completed.
SQL>
Если вы настаиваете на том, чтобы сделать это по-своему, по крайней мере, объявите одну переменную курсора вместо отдельных переменных.
SQL> declare
2 cursor c1 is
3 select t.customer_id,
4 t.customer_name,
5 c.coin_id,
6 c.price,
7 i.delivery_date
8 from invoice i join customer t on i.customer_id = t.customer_id
9 join coin c on i.coin_id = c.coin_id
10 where i.delivery_date between date '2021-05-18' and date '2021-05-20';
11 cur_r c1%rowtype;
12 begin
13 open c1;
14 loop
15 fetch c1 into cur_r;
16 exit when c1%notfound;
17
18 dbms_output.put_line(cur_r.customer_id
19 || ' '
20 || cur_r.coin_id
21 || ' '
22 || cur_r.price
23 || ' '
24 || cur_r.delivery_date);
25 end loop;
26 end;
27 /
1 1 100 19.05.2021
PL/SQL procedure successfully completed.
SQL>
Ответ №2:
Вы используете неправильный синтаксис для объявления курсора. Правильный код должен выглядеть одинаково —
DECLARE
c_id c_customer.customer_name%type;
coin_id1 i_invoice.coin_id%type;
coin_price c_coin.price%type;
delivery i_invoice.delivery_date%type;
-- CURSOR i_invoice ,c_coin ,c_customer is --> This is incorrect declaration.
CURSOR invoice_dtls IS
SELECT customer_name, coin_id, price ,delivery_date
FROM ((invoice INNER JOIN customer on invoice.customer_id = customer.customer_id)
INNER JOIN coin on invoice coin_id = coin.coin_id)
WHERE delivery_date BETWEEN '2021-05-18' AND '2021-05-20'
-- You are missing a semi-colon after this
;
BEGIN
-- OPEN i_invoice,c_customer,c_coin;
OPEN invoice_dtls;
LOOP
/*FETCH c_customers into customer_id ,
c_coin into coin_id,
c_coin into price,
i_invoice into delivery_date;*/
FETCH invoice_dtls
INTO c_id, coin_id1, coin_price, delivery;
EXIT WHEN i_invloice%notfound;
dbms_output.put_line(c_id || ' ' || coin_id1 || ' '
|| coin_price || ' ' || delivery);
END LOOP;
CLOSE i_invoice;
END;
/
Комментарии:
1. продолжайте получать ошибку здесь: ОТКРОЙТЕ i_invoice,c_customer,c_coin;
2. Попробуйте мой отредактированный код. Я прокомментировал эту строку.
3. ошибка в вашем коде появляется здесь: ВЫБЕРИТЕ имя пользователя, идентификатор монеты, цену ,дату доставки
4. Попробуй сейчас. Я обновил формат даты.
5. @taahirmia — Даже при повторных исправлениях и корректировках вы, похоже, все еще сопротивляетесь публикации фактического сообщения об ошибке . Программное обеспечение выдает коды ошибок и текст сообщения по определенной причине. Пожалуйста, помогите тем, от кого вы ожидаете помощи, и опубликуйте сообщения об ошибках .