29.7. SQL dinâmico

Em muitos casos, a declaração SQL a ser utilizada pelo aplicativo já é conhecida na hora em que o aplicativo é escrito. Em alguns casos, entretanto, as declarações SQL são formadas em tempo de execução, ou fornecidas por uma fonte externa. Nestes casos, a declaração SQL não pode ser incorporada diretamente ao código fonte C, mas existe um mecanismo que permite executar declarações SQL arbitrárias especificadas através de variáveis do tipo cadeia de caractere.

A forma mais simples de executar uma declaração SQL arbitrária é utilizando o comando EXECUTE IMMEDIATE. Por exemplo:

EXEC SQL BEGIN DECLARE SECTION;
const char *declaracao = "CREATE TABLE test1 (...);";
EXEC SQL END DECLARE SECTION;

EXEC SQL EXECUTE IMMEDIATE :declaracao;

As declarações que trazem dados (por exemplo, SELECT), não podem ser executadas desta forma.

Uma forma mais poderosa de executar declarações SQL arbitrárias é preparar uma vez, e executar a declaração preparada tantas vezes quanto se desejar. Também é possível preparar uma versão generalizada da declaração, e executar versões específicas desta fazendo a substituição de parâmetros. Ao preparar a declaração são colocados pontos de interrogação nos locais a serem substituídos posteriormente por parâmetros. Por exemplo:

EXEC SQL BEGIN DECLARE SECTION;
const char *declaracao = "INSERT INTO test1 VALUES(?, ?);";
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE minha_declaracao FROM :declaracao;
 ...
EXEC SQL EXECUTE minha_declaracao USING 42, 'foobar';

Quando a declaração utilizada retorna valores é adicionada a cláusula INTO:

EXEC SQL BEGIN DECLARE SECTION;
const char *declaracao = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3;
EXEC SQL END DECLARE SECTION;

EXEC SQL PREPARE minha_declaracao FROM :declaracao;
 ...
EXEC SQL EXECUTE minha_declaracao INTO v1, v2, v3 USING 37;

O comando EXECUTE pode possuir uma cláusula INTO, uma cláusula USING, as duas, ou nenhuma delas.

Quando a declaração preparada não é mais necessária deve-se liberá-la:

EXEC SQL DEALLOCATE PREPARE nome;
SourceForge.net Logo CSS válido!