A causa raiz
No Oracle você tem três tipos de instruções SQL (e adicionalmente existem blocos PL/SQL):
- Declarações na linguagem de definição de dados (DDL). Essas instruções modificam a estrutura do banco de dados. Geralmente começam com os verbos "ALTER" ou "CREATE"
- Declarações na linguagem de modificação de dados (DML). Essas instruções modificam o conteúdo dentro das tabelas, deixando a estrutura de cada tabela inalterada. Essas instruções geralmente começam com "INSERT", "MERGE" ou "DELETE".
- Declarações no que chamo de "linguagem de consulta" (parece não haver um nome canônico para elas). Essas declarações começam com o verbo "SELECT".
As variáveis de ligação no Oracle são permitidas apenas em alguns lugares especiais em DML e instruções de consulta. Você está tentando usar variáveis de ligação em locais onde elas não são permitidas. Daí o erro.
Solução
Construa sua instrução sem variáveis de ligação. Em vez disso, crie a string de consulta completa usando a concatenação de strings.
Se você quiser limpar a entrada antes de concatenar a string, use o pacote DBMS_ASSERT.
Plano de fundo
As variáveis de ligação só podem ser usadas quando o Oracle pode construir um plano de consulta sem saber o valor da variável. Para instruções DDL, não há plano de consulta. Portanto, variáveis de ligação não são permitidas.
Em DML e comandos de consulta, as variáveis de ligação só são permitidas, quando usadas dentro de uma tupla (em relação à teoria dos conjuntos subjacente), ou seja, quando o valor será comparado com o valor em uma tabela ou quando o valor for inserido em uma tabela . Eles não têm permissão para alterar a estrutura do plano de execução (por exemplo, alterar a tabela de destino ou alterar o número de comparações).