Você não pode usar ponto e vírgula em EXECUTE IMMEDIATE
para declarações simples
Aqui está uma citação da documentação :
Remova o ponto e vírgula de
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
Mas há outro problema.
Você precisa entender como as variáveis de substituição (&variable
) funciona
O SQL*Plus solicitará variáveis de substituição apenas uma vez:logo antes do script compilar, antes de executá-lo. E então as variáveis são substituídas no script literalmente, após o que ele será compilado e executado.
Por exemplo, quando você executa seu script, o SQL*Plus reconhece que existem dois literais desconhecidos (
&colname
e &coldata
), e solicitará para você. Se você fornecer os valores 'idade' e 'número' para eles, o SQL*Plus reescreverá o script assim: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;
Portanto, se você deseja atribuir uma string literal a uma variável e deseja obter essa string de uma variável de substituição, precisa fazer isso:
colname varchar2(30) := '&colname'; -- notice the single quotes
Supondo que você forneceu 'idade' para
colname
O SQL*Plus converterá isso para:colname varchar2(30) := 'age';
Portanto, colocar uma variável de substituição dentro de um loop não fará com que o SQL*Plus solicite repetidamente seu valor .