As variáveis de ligação não são permitidas em instruções DDL. Portanto, as seguintes declarações causarão erros:
-
Exemplo nº 1:instrução DDL . Causará ORA-01027:variáveis de ligação não permitidas para operações de definição de dados
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT :def_val )' USING 42;
-
Exemplo nº 2:instrução DDL . Causará ORA-00904::identificador inválido
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( :col_name NUMBER )' USING var_col_name;
-
Exemplo nº 3:instrução SCL . Causará ORA-02248:opção inválida para ALTER SESSION
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = :cal' USING var_calendar_option;
Problema
Para entender por que isso acontece, precisamos examinar Como as instruções SQL dinâmicas são processadas.
Normalmente, um programa aplicativo solicita ao usuário o texto de uma instrução SQL e os valores das variáveis do host usadas na instrução. Em seguida, o Oracle analisa a instrução SQL. Ou seja, o Oracle examina a instrução SQL para garantir que ela siga as regras de sintaxe e se refira a objetos de banco de dados válidos. A análise também envolve a verificação dos direitos de acesso ao banco de dados , reservando os recursos necessários e encontrando o caminho de acesso ideal.
Ênfase adicionada pelo respondente
Observe que a etapa de análise ocorre antes vinculando quaisquer variáveis à instrução dinâmica. Se você examinar os quatro exemplos acima, perceberá que não há como o analisador garantir a validade sintática dessas instruções SQL dinâmicas sem conhecer os valores das variáveis de ligação.
- Exemplo nº 1 :O analisador não pode dizer se o valor de ligação será válido. E se em vez de
USING 42
, o programador escreveuUSING 'forty-two'
? - Exemplo nº 2 :O analisador não pode dizer se
:col_name
seria um nome de coluna válido. E se o nome da coluna vinculada fosse'identifier_that_well_exceeds_thirty_character_identifier_limit'
? - Exemplo nº 3 :Valores para
NLS_CALENDAR
são construídas em constantes (para uma determinada versão do Oracle?). O analisador não pode dizer se a variável vinculada terá um valor válido.
Portanto, a resposta é que você não pode vincular elementos de esquema, como nomes de tabelas, nomes de colunas em SQL dinâmico. Nem você pode vincular constantes incorporadas .
Solução
A única maneira de fazer referência a elementos/constantes de esquema dinamicamente é usar a concatenação de strings em instruções SQL dinâmicas.
-
Exemplo nº 1:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table ( dummy_column NUMBER DEFAULT ' || to_char(42) || ')';
-
Exemplo nº 2:
EXECUTE IMMEDIATE 'CREATE TABLE dummy_table (' || var_col_name || ' NUMBER )';
-
Exemplo nº 3:
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CALENDAR = ''' || var_calendar_option || '''';