Nie możesz używać średników w EXECUTE IMMEDIATE
dla pojedynczych oświadczeń
Oto cytat z dokumentacji :
Usuń średnik z EXECUTE IMMEDIATE
.
execute immediate 'create table smap1(nam varchar2(10));'; -- this is your code
execute immediate 'create table smap1(nam varchar2(10))'; -- correct code, no semicolon at end
Ale jest inny problem.
Musisz zrozumieć, jak zmienne podstawiania (&variable
) działa
SQL*Plus poprosi o podstawianie zmiennych tylko raz:tuż przed kompilacją skryptu, przed jego uruchomieniem. A następnie zmienne są zastępowane dosłownie w skrypcie, po czym zostaną skompilowane i wykonane.
Na przykład po uruchomieniu skryptu SQL*Plus rozpoznaje dwa nieznane literały (&colname
i &coldata
) i wyświetli monit. Jeśli podasz dla nich wartości „wiek” i „liczba”, SQL*Plus przepisze skrypt w następujący sposób:
declare
-- omitted to add clarity
begin
execute immediate 'create table smap1(nam varchar2(10));';
if(no_of_cols>=2) then
for i in 2..no_of_cols loop
colname:=age;
coldata:=number;
execute immediate 'alter table smapl add '||colname||' '||coldata;
end loop;
end if;
end;
Więc jeśli chcesz przypisać literał ciągu do zmiennej i chcesz pobrać ten ciąg ze zmiennej zastępczej, musisz zrobić to:
colname varchar2(30) := '&colname'; -- notice the single quotes
Zakładając, że podałeś „wiek” dla colname
SQL*Plus z radością przekonwertuje to na:
colname varchar2(30) := 'age';
Tak więc umieszczenie zmiennej zastępującej wewnątrz pętli nie spowoduje, że SQL*Plus będzie wielokrotnie pytał o jej wartość .