Escolar Documentos
Profissional Documentos
Cultura Documentos
Com esta dica pretendo apresentar recursos que auxiliem no uso de SQL Dinmico
nativo do banco de dados Oracle. Este recurso permite a criao de interfaces de
programao (com um PL/SQL, um Pro*Cobol, Form, etc) mais flexveis e versteis
(com construes de comandos em tempo de execuo).
Muitos programas realizam operaes especficas e previsveis, como solicitar um
cdigo de um produto e atualizar o seu valor em um percentual pr-determinado.
Neste caso, o texto completo do comando, por exemplo, UPDATE, conhecido em
tempo de compilao, pois tal comando no muda de execuo para execuo, o
que conhecido como comando SQL esttico.
Por outro lado, alguns programas precisam construir e processar comandos SQL
definidos em tempo de execuo. Por exemplo, em um relatrio genrico o
desenvolvedor precisa construir diferentes comandos SELECT para a gerao de
vrios relatrios diferentes, com base em escolhas selecionadas em tempo de
execuo pelo usurio final da aplicao. Neste caso, o texto completo do comando
conhecido somente no momento de sua execuo (ou seja, ele pode mudar de
execuo para execuo), sendo conhecido como comando SQL dinmico.
Um SQL Dinmico um comando SQL ou um bloco PL/SQL vlido, codificado
dentro de uma string (populada em tempo de execuo) e pode ser executado
atravs do uso do comando EXECUTE IMMEDIATE, a partir da verso 8i do banco
de dados Oracle. Esse tipo de comando SQL pode conter placeholders para bind
(host) arguments (como demonstrado na sintaxe adiante). Um placeholder um
identificador no declarado, ento o valor que lhe atribudo substitui uma
varivel da composio da sintaxe do comando, sendo que preciso prefixar tal
coluna com o smbolo : (dois pontos).
Com o uso de SQL Dinmico possvel, ento, flexibilizar sistemas e adicionar a
possibilidade de execuo de comandos DDL (Data Definition Language
Linguagem de Definio de Dados, como CREATE TABLE, TRUNCATE TABLE, ALTER
TABLE, ALTER SESSION, GRANT, etc) dentro de blocos PL/SQL (em um bloco
PL/SQL esses comandos no podem ser executados estaticamente).
Um comando DML (Data Manipulation Language Linguagem de Manipulao de
Dados, como SELECT, UPDATE, DELETE e INSERT) de contedo flexvel (como
diferentes condies para uma clusula WHERE ou SELECT) tambm pode ser
executado atravs de SQL Dinmico.
Sintaxe:
EXECUTE IMMEDIATE SQL string'
[INTO {varivel[, varivel]...
| record}]
[USING [IN | OUT | IN OUT] bind_argument
[, [IN | OUT | IN OUT] bind_argument]...];
Onde:
A SQL String uma string que contm aquilo que se deseja executar. Com
exceo de consultas que retornem mais de uma linha, a string pode conter
qualquer comando SQL (sem o terminador, seno ser considerado um bloco
PL/SQL) ou qualquer bloco PL/SQL (com o terminador). A string tambm pode
conter placeholders (por exemplo :vl_salario) e bind_arguments. No caso da SQL
String representar um PL/SQL necessrio que este contenha, pelo menos begin
e end.
Na clusula INTO , a especificao de variveis opcional e indica uma ou mais
variveis para as quais valores selecionados (em uma consulta constante na SQL
String) sero atribudos. J um record baseado em um TYPE ou %ROWTYPE
especificado pelo usurio e que pode receber uma linha inteira retornada por uma
consulta constante na SQL String. Em suma, esta clusula somente utilizada
quando a SQL String for uma consulta (SELECT) que retorne somente uma linha e o
tipo da varivel ou registro deve ser compatvel com o valor a ser recebido.
Na clusula USING , a seo bind_argument (parmetros) opcional e designa
uma valor / argumento a ser atribudo / repassado para bind variables na SQL
string. Os bind_arguments no podem ser utilizados para repassar nomes de
objetos de um esquema (como nomes de tabelas ou de colunas). Podem ser
utilizadas expresses numricas, alfanumricas e de datas, mas nunca um valor do
tipo booleano ou de contedo NULL. Os tipos definidos pelo usurio, como objetos,
colees e REFs (tipos no suportados pela package DBMS_SQL) tambm so
suportados pelo comando EXECUTE IMMEDIATE. Todo bind_argument deve constar
na clusula USING e em tempo de execuo, todo bind_argument na clusula
USING ir repassar um correspondente placeholder na SQL string.
Observao 1: Para a execuo de commandos DDL, necessrio que tenham
sido concedidos os privilgios necessrios para o usurio de execuo, caso
contrrio, o erro ORA-1031 Insufficient privileges ser apresentado.
Observao 2: O comando EXECUTE IMMEDIATE no reconhecido na ferramenta
Oracle Developer 6.0, bem como pelo PL/SQL 8.0.6.3.
Algumas consideraes devem ser feitas:
1) EXECUTE IMMEDIATE no realizar automaticamente o COMMIT de uma
transao DML anterior. Se um comando DML processado via EXECUTE
IMMEDIATE necessrio um COMMIT explcito para efetivar transaes pendentes
antes ou como parte do prprio EXECUTE IMMEDIATE. Se um commando DDL
processado via EXECUTE IMMEDIATE ir, automaticamente, as transaes
pendentes.
2) Consultas que retornem mais de uma linha no so suportadas como valor de
retorno e neste caso, a alternativa utilizar uma tabela temporria para armazenar
os registros ou utilizar REF cursores. A seguir apresentado um exemplo de um
comando EXECUTE IMMEDIATE que popula uma tabela temporria para futuro
processamento.
3) No possvel utilizar o estilo de comentrio do padro ANSI (- - ...) em um
bloco PL/SQL que ser processado dinamicamente, pois o que houver aps estes
caracteres ser ignorado. Aconselha-se ento, a utilizar o estilo de comentrio da
linguagem C (/* ... */).
4) Comandos SQL criados e executados dinamicamente apresentam overhead em
performance, mas o comando EXECUTE IMMEDIATE visa reduzir este overhead e