Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 35. PL/pgSQL - Linguagem procedural SQL | Fim | Próxima |
Autor: Halley Pacheco de Oliveira (<halleypo@users.sourceforge.net> ). Iniciado em 2007-02-26.
Transact-SQL é a linguagem que contém os comandos utilizados para administrar as instâncias do SQL Server, criar e gerenciar todos os objetos em uma instãncia do SQL Server, e para inserir, trazer, modificar e excluir todos os dados das tabelas do SQL Server. Transact-SQL é uma extensão da linguagem definida nos padrões SQL publicados pela International Standards Organization (ISO) e pela American National Standards Institute (ANSI) ( SQL Server 2005 Books Online — Glossary of Terms).
Transact-SQL é essencial para o SQL Server. Todos os aplicativos que se comunicam com uma instância do SQL Server o fazem enviando instruções Transact-SQL para o servidor, não importando a interface de usuário do aplicativo
O comando CREATE FUNCTION cria uma função definida pelo usuário. Esta é uma rotina Transact-SQL ou CLR (common language runtime) salva, que retorna um valor. As funções definidas pelo usuário não podem ser utilizadas para realizar ações que modificam o estado do banco de dados. As funções definidas pelo usuário, assim como as funções do sistema, podem ser chamadas de uma consulta. As funções escalares podem ser executadas utilizando a instrução EXECUTE, como os procedimentos armazenados.
Esta seção mostra, através de exemplos, a conversão de funções definidas pelo usuário escritas em Transact-SQL em funções escritas em PL/pgSQL, para ajudar aos desenvolvedores na conversão de aplicativos do SQL Server para o PostgreSQL.
No Transact-SQL a variável local é definida na instrução DECLARE @variável_local, e o valor atribuído através da instrução SET @variável_local. Também pode ser atribuído valor à variável local através da instrução SELECT @variável_local, mas não é recomendado. O nome da variável local sempre começa com o símbolo @ precedendo seu nome.
No PL/pgSQL todas as variáveis utilizadas em um bloco devem ser declaradas na seção de declarações do bloco (A única exceção é a variável de laço do FOR interagindo sobre um intervalo de valores inteiros, que é automaticamente declarada como sendo do tipo inteiro). Também pode ser atribuído valor a variável no momento de sua declaração, e não há nenhum caractere especial para indicar que a variável é local.
A Tabela 35-1 mostra os elementos da linguagem de controle de fluxo do Transact-SQL e os elementos equivalentes do PL/pgSQL.
Tabela 35-1. Controle de fluxo no Transact-SQL e no PL/pgSQL
Transact-SQL | PL/pgSQL |
---|---|
BEGIN { instrução_sql | bloco_de_instruções } END |
[ <<rótulo>> ] [ DECLARE declarações ] BEGIN instruções END; |
BREAK |
EXIT [ rótulo ] [ WHEN expressão ]; |
CONTINUE |
|
rótulo: GOTO rótulo |
|
IF expressão_booleana { instrução_sql | bloco_de_instruções } [ ELSE { instrução_sql | bloco_de_instruções } ] |
IF expressão_booleana THEN instruções [ ELSE instruções ] END IF; IF expressão_booleana THEN instruções [ ELSIF expressão_booleana THEN instruções [ ELSIF expressão_booleana THEN instruções ...]] [ ELSE instruções ] END IF; ... |
RETURN expressão
|
RETURN expressão;
|
BEGIN TRY { instrução_sql | bloco_de_instruções } END TRY BEGIN CATCH { instrução_sql | bloco_de_instruções } END CATCH [ ; ] |
[ <<rótulo>> ] [ DECLARE declarações ] BEGIN instruções EXCEPTION WHEN condição [ OR condição ... ] THEN instruções_do_tratador [ WHEN condição [ OR condição ... ] THEN instruções_do_tratador ... ] END; |
WHILE expressão_booleana { instrução_sql | bloco_de_instruções } [ BREAK ] { instrução_sql | bloco_de_instruções } [ CONTINUE ] { instrução_sql | bloco_de_instruções } |
[<<rótulo>>] WHILE expressão LOOP instruções END LOOP; |
Exemplo 35-11. Função StrSeparate em Transact-SQL e PL/pgSQL
Neste exemplo a função StrSeparate, desenvolvida por Alexander Chigrik (<chigrik@mssqlcity.com> ) e publicada em String User-Defined Functions (UDF), é convertida de Transact-SQL para PL/pgSQL. A finalidade desta função é inserir um caractere em uma cadeia de caracteres após cada n caracteres (a partir o final da cadeia de caracteres).
Sinopse:
onde str é a cadeia de caracteres onde o caractere c será inserido após cada n caracteres da direita para a esquerda.Listagem da função em Transact-SQL:
CREATE FUNCTION StrSeparate ( @str varchar(4000), @c varchar(1), @n int ) RETURNS varchar(4000) AS BEGIN DECLARE @i int, -- número do passo @j int, -- posição para inserir o caractere @p int -- número de passos IF (len(@str) <= @n) RETURN @str SET @str = REVERSE(@str) SET @i = 1 SET @j = @n + 1 SET @p = len(@str) / @n WHILE @i <= @p BEGIN SET @str = ISNULL(STUFF(@str, @j, 0, @c), @str) SET @j = @j + @n + 1 SET @i = @i + 1 END RETURN REVERSE(@str) END
Listagem da função convertida para PL/pgSQL:
CREATE OR REPLACE FUNCTION REVERSE ( str text ) RETURNS text AS $$ DECLARE s text := ''; -- cadeia de caracteres de trás para frente i int; -- posição do caractere BEGIN IF (length(str) <= 1) THEN RETURN str; END IF; FOR i IN REVERSE length(str) .. 1 LOOP s := s || substr(str,i,1); END LOOP; RETURN s; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION StrSeparate ( str varchar(4000), c varchar(1), n int ) RETURNS varchar(4000) AS $$ DECLARE p int; -- número de passos i int := 1; -- número do passo j int := n + 1; -- posição para inserir o caractere s text := REVERSE(str); -- cadeia de caracteres de trás para frente BEGIN IF (length(str) <= n) THEN RETURN str; END IF; p := length(s) / n; WHILE i <= p LOOP s := COALESCE((substr(s, 1, j-1) || c || substr(s, j)),s); j := j + n + 1; i := i + 1; END LOOP; RETURN REVERSE(s); END $$ LANGUAGE plpgsql; SELECT StrSeparate('12345678',' ',3); strseparate ------------- 12 345 678
Devem ser observadas as seguintes diferenças entre a função StrSeparate escrita em Transact-SQL e sua versão escrita em PL/pgSQL:
Foi necessário escrever a função REVERSE nativa do Transact-SQL em PL/pgSQL, porque esta função não existe no PostgreSQL.
No Transact-SQL os nomes das variavéis locais começam sempre com o símbolo @, enquanto no PL/pgSQL os nomes das variáveis não possuem nenhum caractere especial para indicar que a variável é local.
No Transact-SQL as variavéis são definidas na instrução DECLARE, enquanto no PL/pgSQL as variáveis são definidas na seção DECLARE.
No Transact-SQL o valor inicial das variavéis é atribuído através da instrução SET (ou SELECT), enquanto no PL/pgSQL o valor inicial das variáveis é atribuído na seção DECLARE.
No Transact-SQL o valor da variável é atribuído através da instrução SET (ou SELECT), enquanto no PL/pgSQL o valor da variável é atribuído diretamente, sem necessidade de nenhuma instrução SQL para esta operação (Embora a expressão nesta instrução seja avaliada através de um comando SELECT do SQL enviado para o servidor de banco de dados).
No Transact-SQL o parâmetro da função pode ser operado e seu valor modificado no corpo da função, enquanto no PL/pgSQL o parâmetro da função é uma constante e, portanto, seu valor não pode ser modificado.
No Transact-SQL é utilizado o operador de atribuição "=" para atribuir um valor a uma variável, enquanto no PL/pgSQL é utilizado o operador ":=".
No Transact-SQL o bloco IF não inclui as palavras chave THEN e END IF, enquanto no PL/pgSQL estas palavras chave são necessárias.
No Transact-SQL a construção WHILE utiliza BEGIN e END para envolver o bloco de instruções, enquanto no PL/pgSQL é utilizado LOOP e END LOOP para envolver o bloco de instruções.
No Transact-SQL o fim da instrução não é marcado por um caractere especial, enquanto no PL/pgSQL o fim da instrução é marcado pelo caractere ponto-e-vírgula (;).