Проблема с простой программой PL/SQL
Вот моя простая программа на PL/SQL:
DECLARE
CURSOR c1 is
SELECT typ, specifikacia_typu, spz FROM Auta
WHERE (substr(spz, 1, 2) = 'KE' OR substr(spz, 1, 2) = 'KS') AND ROWNUM <= 2;
CURSOR c2 is
SELECT typ, specifikacia_typu, spz FROM Auta
WHERE substr(spz, 1, 2) <> 'KE' AND substr(spz, 1, 2) <> 'KS';
my_typ CHAR(10);
my_specifikacia_typu CHAR(15);
my_spz CHAR(8);
BEGIN
-- vytovirt potrebne tabulky pre kosicke a nekosicke auta
CREATE TABLE Kosicke (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);
CREATE TABLE Ostatne (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);
-- prve dve auta z Kosic vlozit do tabulky Kosicke
OPEN c1;
FOR i IN 1..2 LOOP
FETCH c1 INTO my_typ, my_specifikacia_typu, my_spz;
EXIT WHEN c1%NOTFOUND;
INSERT INTO Kosice VALUES(my_typ, my_specifikacia_typu, my_spz);
COMMIT;
END LOOP;
CLOSE c1;
-- auta, ktore nie su z Kosic vlozit do tabulky Ostatne
OPEN c2;
LOOP
FETCH c2 INTO my_typ, my_specifikacia_typu, my_spz;
EXIT WHEN c2%NOTFOUND;
INSERT INTO Ostatne VALUES(my_typ, my_specifikacia_typu, my_spz);
COMMIT;
END LOOP;
CLOSE c1;
END;
/
Когда я запускаю Oracle 10g Express Edition, я получаю эту ошибку:
ORA-06550: line 16, column 5:
PLS-00103: Encountered the symbol "CREATE" when expecting one of the following:
begin case declare exit for goto if loop mod null pragma
raise return select update while with
<<
close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe
1. DECLARE
2.
3. CURSOR c1 is
Я не уверен, в чем проблема, и это моя первая программа, которую я написал на PL/SQL, поэтому я немного растерялся. Я использовал этот пример программ с веб-сайта Oracle для написания этой программы: http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/a_samps.htm
РЕДАКТИРОВАТЬ:
Кроме того, когда я сначала создаю таблицы вне программы, а затем запускаю программу, я получаю эту ошибку:
ORA-06550: line 17, column 21:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 17, column 9:
PL/SQL: SQL Statement ignored
1. DECLARE
2. CURSOR c1 is
3. SELECT typ, specifikacia_typu, spz FROM Auta
Что не имеет смысла, потому что таблица "Auta" существует, все таблицы, используемые в программе, существуют.
3 ответа
Хорошо, просто чтобы вы знали, как я решил проблему (я уже решил ее, пока никто не ответил).
Сначала я создал таблицы вне программы с помощью обычных SQL-запросов:
CREATE TABLE Kosicke (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);
CREATE TABLE Ostatne (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
);
И я отредактировал программу так (она уже работает):
DECLARE
CURSOR c1 is
SELECT typ, specifikacia_typu, spz FROM Auta
WHERE (substr(spz, 1, 2) = 'KE' OR substr(spz, 1, 2) = 'KS') AND ROWNUM <= 2;
CURSOR c2 is
SELECT typ, specifikacia_typu, spz FROM Auta
WHERE substr(spz, 1, 2) <> 'KE' AND substr(spz, 1, 2) <> 'KS';
my_typ CHAR(10);
my_specifikacia_typu CHAR(15);
my_spz CHAR(8);
BEGIN
/* prve dve auta z Kosic vlozit do tabulky Kosicke */
OPEN c1;
FOR i IN 1..2 LOOP
FETCH c1 INTO my_typ, my_specifikacia_typu, my_spz;
EXIT WHEN c1%NOTFOUND;
INSERT INTO Kosicke VALUES(my_typ, my_specifikacia_typu, my_spz);
COMMIT;
END LOOP;
CLOSE c1;
/* auta, ktore nie su z Kosic vlozit do tabulky Ostatne */
OPEN c2;
LOOP
FETCH c2 INTO my_typ, my_specifikacia_typu, my_spz;
EXIT WHEN c2%NOTFOUND;
INSERT INTO Ostatne VALUES(my_typ, my_specifikacia_typu, my_spz);
COMMIT;
END LOOP;
CLOSE c2;
END;
/
Помимо проблемы с синтаксисом, которую объяснил Тони, этот код должен быть просто вставкой SQL без каких-либо курсоров. Если вам действительно нужен курсор, попробуйте использовать неявный курсор перед использованием явного.
Вы не можете выполнить DDL как CREATE TABLE непосредственно в PL/SQL. Тем не менее, вы можете сделать это с помощью динамического PL / SQL следующим образом:
-- vytovirt potrebne tabulky pre kosicke a nekosicke auta
EXECUTE IMMEDIATE 'CREATE TABLE Kosicke (
typ CHAR(10),
specifikacia_typu CHAR(15),
spz CHAR(8)
)';
Ваши вставки также должны быть динамическими, так как таблицы не существуют во время компиляции, и поэтому код недействителен:
EXECUTE IMMEDIATE 'INSERT INTO Ostatne VALUES(:p1, :p2, :p3)'
USING my_typ, my_specifikacia_typu, my_spz;
Было бы интересно узнать, зачем вам это нужно: в Oracle практически никогда не нужно создавать таблицы "на лету", и обычно это не очень хорошая идея.