Не можете да използвате точка и запетая в EXECUTE IMMEDIATE
за единични изрази
Ето цитат от документацията :
Премахнете точката и запетая от 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
Но има друг проблем.
Трябва да разберете как заместващите променливи (&variable
) работи
SQL*Plus ще поиска променливи за заместване само веднъж:точно преди скриптът да се компилира, преди да го изпълните. След това променливите се заменят дословно в скрипта, след което той ще бъде компилиран и изпълнен.
Например, когато изпълнявате своя скрипт, SQL*Plus разпознава, че има два неизвестни литерала (&colname
и &coldata
) и ще ви подкани. Ако предоставите стойностите 'age' и 'number' за тях, SQL*Plus ще пренапише скрипта по следния начин:
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;
Така че, ако искате да присвоите низов литерал на променлива и искате да получите този низ от заместваща променлива, трябва да направите следното:
colname varchar2(30) := '&colname'; -- notice the single quotes
Ако приемем, че сте предоставили „възраст“ за colname
SQL*Plus с радост ще преобразува това в:
colname varchar2(30) := 'age';
Така че поставянето на заместваща променлива вътре в цикъл няма да накара SQL*Plus многократно да ви подканя за нейната стойност .