PL/SQL

linguagem de programação

PL/SQL (acrónimo para a expressão inglesa Procedural Language/Structured Query Language) é uma extensão da linguagem padrão SQL para o SGBD Oracle da Oracle Corporation. É uma linguagem procedural da Oracle que estende a linguagem SQL.[1][2]

Permite que a manipulação de dados seja incluída em unidades de programas. Blocos de PL/SQL são passados e processados por uma PL/SQL Engine que pode estar dentro de uma ferramenta Oracle ou do Server. A PL/SQL Engine filtra os comandos SQL e manda individualmente o comando SQL para o SQL Statement Executor no Oracle Server, que processa o PL/SQL com os dados retornados do Server.

É a linguagem básica para criar programas complexos e poderosos, não só no banco de dados, mas também em diversas ferramentas Oracle.

Antes de 1991 a única forma de usar construções procedurais com o SQL era usar PRO*C. Foi onde as instruções SQL do Oracle foram embutidas em código C. O código C era pré-compilado para converter as instruções SQL em chamadas de bibliotecas.

Em 1991 o PL/SQL 1.0 foi lançado com o Oracle Versão 6.0. Ele era muito limitado nas suas capacidades.

Já a versão 2.0 era uma atualização maior, que suportava stored packages, procedures, funções, tabelas PL/SQL, registros definidos pelo programador e package extensions. Esta versão foi lançada com o Oracle Versão 7.0.

O PL/SQL Versão 2.1 foi liberado com a Versão 7.1 do Oracle. Isto permitiu o uso de stored functions dentro de instruções SQL e a criação de SQL dinâmico pelo uso do pacote DBMS_SQL. Foi também possível executar instruções de Linguagens de Definição de Dados de programas PL/SQL.

A Versão 2.2 PL/SQL foi lançada com a Versão 7.2 do Oracle. Ele implementava uma proteção do código para programas PL/SQL e também o agendamento de trabalhos do banco de dados com o pacote DBMS_JOB.

A Versão 2.3 do PL/SQL foi lançado com a Versão 7.3 do Oracle. Esta versão aumentou as capacidades das tabelas PL/SQL e adicionou funcionalidades de E/S de arquivos.

A Versão 2.4 do PL/SQL foi liberada com a Versão 8.0 do Oracle. Esta versão suporta os melhoramentos do Oracle 8, incluindo Large Objects, projeto orientado a objetos, tabelas aninhadas e Oracle advanced queuing.

Estrutura Básica da PL/SQL editar

Com PL/SQL, você pode usar instruções SQL para manipular dados do Oracle e controle de fluxo para processar os dados. Além disso, você pode declarar constantes e variáveis, definir procedimentos e funções. Assim, PL/SQL combina o poder de manipulação dos dados de SQL com o poder de processamento de dados das linguagens procedurais.[3]

As unidades básicas (procedimentos, funções e blocos anônimos) que compõem um programa PL/SQL são blocos lógicos, que podem conter qualquer número de sub-blocos aninhados. Tipicamente, cada bloco lógico corresponde a um problema ou subproblema a ser resolvido. Assim, PL/SQL suporta a "abordagem dividir para conquistar" para a resolução de problemas chamado refinamento passo a passo.[3]

Um bloco (ou sub-bloco) permite agrupar declarações logicamente relacionadas. Dessa forma, você pode colocar declarações perto de onde elas são usadas. As declarações são locais para o bloco e deixam de existir quando o bloco é concluído.[3]

A unidade básica em PL/SQL é um bloco. Todos os programas em PL/SQL são compostos por blocos, que podem estar localizados uns dentro dos outros. Geralmente, cada bloco efetua uma ação lógica no programa. Um bloco tem basicamente a seguinte estrutura:

DECLARE

Seção para declaração de variáveis,tipos e subprogramas locais.

BEGIN

Seção Executável, nesta seção ficam as instruções procedimentais e SQL. Esta é a única seção do bloco que é indispensável e obrigatória.

EXCEPTION

Seção/Setor onde ficam as instruções de exceção. Ex: valor vazio, valor duplicado

END

A ordem das partes segue uma lógica. Primeiro vem a parte declarativa, em quais objetos podem ser declarados. Uma vez declarados, os objetos podem ser manipulados na parte executável. Exceções que surgem durante a execução podem ser tratadas na parte de tratamento de exceção.[3]

Você pode aninhar sub-blocos na parte executável e na de tratamento de exceções de um bloco PL/SQL ou subprograma, mas não na parte declarativa. Além disso, você pode definir subprogramas locais na parte declarativa de qualquer bloco. No entanto, você pode chamar subprogramas locais só a partir do bloco em que eles são definidos.[3]

Tipos de Dados da PL/SQL editar

Toda constante, variável, parâmetro e função da PL/SQL retorna um valor como um tipo de dado, tipo esse, que determina seu formato de armazenamento e seus valores e operações válidos.[4]

A PL/SQL tem muitos tipos e subtipos de dados no pacote STANDARD e permite que você defina seus próprios subtipos. Os principais tipos de dados da PL/SQL são:

  • Os tipos de dados SQL;
  • BOOLEAN;
  • PLS_INTEGER e BINARY_INTEGER;
  • REF CURSOR e SYS_REFCURSOR;
  • Subtipos definidos pelo usuário.

BOOLEAN editar

O tipo BOOLEAN armazena valores lógicos, que são os valores booleanos TRUE e FALSE e o valor NULL que representa um valor desconhecido.

A sintaxe para declarar uma variável BOOLEAN é:[5]

nome_variavel BOOLEAN

O único valor que você pode atribuir a uma variável BOOLEAN é uma expressão booleana. Por exemplo:

DECLARE
  nome_variavel BOOLEAN;
BEGIN
  -- Essas estruturas de repetição do tipo WHILE são equivalentes

  nome_variavel := FALSE;
  WHILE nome_variavel = FALSE
    LOOP
      nome_variavel := TRUE;
    END LOOP;

  nome_variavel := FALSE;
  WHILE NOT (nome_variavel = TRUE)
    LOOP
      nome_variavel := TRUE;
    END LOOP;

  nome_variavel := FALSE;
  WHILE NOT nome_variavel
    LOOP
      nome_variavel := TRUE;
    END LOOP;
END;

Como a SQL não tem um tipo de dado equivalente a BOOLEAN, você não pode:

  • Atribuir um valor booleano a uma coluna da tabela de banco de dados;
  • Selecionar ou buscar o valor de uma coluna da tabela do banco de dados em uma variável BOOLEAN;
  • Usar um valor do tipo BOOLEAN em uma instrução SQL, função SQL ou função PL/SQL chamada de uma instrução SQL.

PLS_INTEGER editar

Os tipos PLS_INTEGER e BINARY_INTEGER são idênticos. Para simplificar, vamos usar PLS_INTEGER para significar PLS_INTEGER e BINARY_INTEGER.

PLS_INTEGER armazena valores inteiros que vão de -2.147.483.648 a 2.147.483.647, representados em 32 bits.

Vantagens do PLS_INTEGER sobre o tipo de dados NUMBER e os subtipos NUMBER:[6]

  • Os valores PLS_INTEGER ocupam menos espaço de armazenamento;
  • As operações PLS_INTEGER usam ULA, portanto, são mais rápidas do que as operações NUMBER, que usam library arithmetic (biblioteca aritmética de software).

Para maior eficiência, use os valores PLS_INTEGER para todos os cálculos de números inteiros que estejam dentro de seu intervalo.

Subtipos de PLS_INTEGER:

  • NATURAL: valores positivos de PLS_INTEGER incluído o 0;
  • NATURALN: valores do subtipo NATURAL e não nulos;
  • POSITIVE: valores positivos de PLS_INTEGER excluído o 0;
  • POSITIVEN: valores do subtipo POSITIVE e não nulos;
  • SIGNTYPE: valores -1, 0 ou 1 (útil para programar lógica de estado triplo);
  • SIMPLE_INTEGER: valores de PLS_INTEGER não nulos.

REF CURSOR editar

Um cursor é um ponteiro para uma área privada da SQL que armazena informações sobre o processamento de uma instrução SELECT ou DML específica. Um cursor de sessão permanece na memória da sessão até que a sessão termine. Um cursor de sessão que é construído e gerenciado pela própria PL/SQL é um cursor implícito. Um cursor de sessão que você constrói e gerencia é um cursor explícito. [7]

Uma variável de cursor é como um cursor explícito, exceto que:[8]

  • Não se limita a uma consulta. Você pode abrir uma variável de cursor para uma consulta, processar o conjunto de resultados e usar a variável de cursor para outra consulta;
  • Você pode atribuir um valor a ele;
  • Você pode usá-lo em uma expressão;
  • Pode ser um parâmetro de subprograma. Você pode usar variáveis ​​de cursor para passar conjuntos de resultados de consulta entre subprogramas;
  • Pode ser uma variável de host. Você pode usar variáveis ​​de cursor para passar resultados de consultas entre subprogramas armazenados e seus clientes;
  • Não pode aceitar parâmetros. Você não pode passar parâmetros para uma variável de cursor, mas pode passar consultas inteiras para ela.

Uma variável de cursor tem essa flexibilidade porque é um ponteiro, ou seja, seu valor é o endereço de um item, não o próprio item.

Antes de fazer referência a uma variável de cursor, você deve fazer com que ela aponte para uma área de trabalho SQL, abrindo-a ou atribuindo a ela o valor de uma variável de cursor ou variável de cursor de host já aberta.

Para criar uma variável de cursor, declare uma variável do tipo SYS_REFCURSOR ou defina um tipo REF CURSOR e então declare a variável. Informalmente, uma variável de cursor às vezes é chamada de REF CURSOR. Para simplificar, vamos usar REF CURSOR para significar SYS_REFCURSOR e REF CURSOR.[9]

A sintaxe básica de um tipo REF CURSOR é:

DECLARE
  TYPE nome_variavel1 IS REF CURSOR RETURN nome_tabela1%ROWTYPE;  -- tipo forte
  TYPE nome_variavel2 IS REF CURSOR;                       -- tipo fraca

  cursor1  nome_variavel1;       -- variável de cursor forte
  cursor2  nome_variavel2;   -- variável de cursor fraca
  meu_cursor1 SYS_REFCURSOR;  -- variável de cursor fraca

  TYPE meu_cursor2 IS REF CURSOR RETURN nome_tabela2%ROWTYPE;  -- tipo forte
  cursor3 meu_cursor2;  -- variável de cursor forte
BEGIN
  NULL;
END;

As variáveis nome_tabela1 e nome_tabela2 podem ser dos tipos de dados:

  • RECORD;
  • Uma tabela ou uma consulta SQL;

Se você especificar o nome_retorno então a sua variável de cursor é forte, senão ela é fraca. Com uma variável de cursor forte você só pode relacionar consultas que retornam o tipo especificado na própria variável de cursor, entretanto, com uma fraca você pode relacionar qualquer consulta.

Abrindo uma variável de cursor:[10]

DECLARE
  TYPE nome_variavel1 IS REF CURSOR RETURN nome_tabela1%ROWTYPE;  -- tipo forte
  TYPE nome_variavel2 IS REF CURSOR;                       -- tipo fraca

  cursor1  nome_variavel1;       -- variável de cursor forte
  cursor2  nome_variavel2;   -- variável de cursor fraca
  meu_cursor1 SYS_REFCURSOR;  -- variável de cursor fraca

  TYPE meu_cursor2 IS REF CURSOR RETURN nome_tabela2%ROWTYPE;  -- tipo forte
  cursor3 meu_cursor2;  -- variável de cursor forte

BEGIN
  OPEN nome_variavel1 FOR SELECT * FROM nome_tabela1;
END;

Fechando uma variável de cursor:[11]

DECLARE
  TYPE nome_variavel1 IS REF CURSOR RETURN nome_tabela1%ROWTYPE;  -- tipo forte
  TYPE nome_variavel2 IS REF CURSOR;                       -- tipo fraca

  cursor1  nome_variavel1;       -- variável de cursor forte
  cursor2  nome_variavel2;   -- variável de cursor fraca
  meu_cursor1 SYS_REFCURSOR;  -- variável de cursor fraca

  TYPE meu_cursor2 IS REF CURSOR RETURN nome_tabela2%ROWTYPE;  -- tipo forte
  cursor3 meu_cursor2;  -- variável de cursor forte

BEGIN
  OPEN nome_variavel1 FOR SELECT * FROM nome_tabela1;
  CLOSE nome_variavel1;
END;

Subtipos Definidos Pelo Usuário editar

A PL/SQL permite que você defina seus próprios subtipos. O tipo base pode ser qualquer tipo de dados PL/SQL como CHAR, DATE ou RECORD incluindo um subtipo definido, anteriormente, pelo usuário.[12]

Os subtipos podem:

  • Fornecer compatibilidade com tipos de dados ANSI/ISO;
  • Mostrar o uso pretendido para o subtipo em questão;
  • Detectar valores fora do intervalo.
DECLARE
  SUBTYPE Cep IS POSITIVEN(8);

BEGIN
  Cep := 12345678;
END;

Ver também editar

Referências

  1. «DB2 9.7: Run Oracle applications on DB2 9.7 for Linux, Unix, and Windows». www.ibm.com. Consultado em 1 de Maio de 2011 
  2. «Literals». Oracle Database SQL Reference 10g Release 2 (10.2). Oracle. Consultado em 20 de março de 2009 
  3. a b c d e Portfolio, Tom (1996). PL/SQL User’s Guide and Reference. [S.l.]: Oracle Corporation. p. 22-23 
  4. «PL/SQL Data Types». Oracle. Consultado em 22 de setembro de 2020 
  5. «BOOLEAN Data Type». Oracle. Consultado em 22 de setembro de 2020 
  6. «PLS_INTEGER and BINARY_INTEGER Data Types». Oracle. Consultado em 22 de setembro de 2020 
  7. «Cursor». Oracle. Consultado em 22 de setembro de 2020 
  8. «Cursor Variables». Oracle. Consultado em 22 de setembro de 2020 
  9. «Creating Cursor Variables». Oracle. Consultado em 22 de setembro de 2020 
  10. «Example 6-30 Procedure to Open Cursor Variable for One Query». Oracle. Consultado em 22 de setembro de 2020 
  11. «Example 6-6 FETCH Statements Inside LOOP Statements». Oracle. Consultado em 22 de setembro de 2020 
  12. «User-Defined PL/SQL Subtypes». Oracle. Consultado em 22 de setembro de 2020 

Ligações externas editar