Oracle Tutorial de tipos de objetos PL/SQL com EXEMPLOS
O que é tipo de objeto em PL/SQL?
A Programação Orientada a Objetos é especialmente adequada para construir componentes reutilizáveis e aplicativos complexos. Eles são organizados em torno de “objetos” e não de “ações”, ou seja, os programas são projetados para trabalhar e interagir com o objeto inteiro e não com uma ação única. Este conceito permite ao programador preencher e manipular os detalhes no nível das entidades do objeto.
A imagem abaixo mostra um exemplo do tipo de objeto em que uma conta bancária é considerada uma entidade objeto. Os atributos do objeto incluem coisas que contêm alguns valores de atributos, por exemplo, em Conta Bancária; é o número da conta, saldo bancário, etc., enquanto os métodos de objeto descrevem coisas como cálculo da taxa de juros, geração de extrato bancário, etc., que requer a conclusão de determinado processo.
Em PL/SQL, a programação orientada a objetos é baseada em tipos de objetos.
Um tipo de objeto pode representar qualquer entidade do mundo real. Discutiremos mais tipos de objetos neste capítulo.
Componentes de tipos de objetos
PL/SQL o tipo de objeto contém principalmente dois componentes.
- Atributos
- Membros/Métodos
Atributos
Atributos são a coluna ou campo em que os dados são armazenados. Cada atributo será mapeado para o tipo de dados que define o tipo de processamento e armazenamento desse atributo. O atributo pode ser de qualquer valor válido Tipo de dados PL/SQLou pode ser de outro tipo de objeto.
Membros/Métodos
Membros ou Métodos são subprogramas definidos no tipo de objeto. Eles não são usados para armazenar quaisquer dados. Eles são usados principalmente para definir processos dentro do tipo de objeto. Para exemplos de validação de dados antes de preencher o tipo de objeto. Eles são declarados na seção de tipo de objeto e definidos na seção de corpo do tipo de objeto. A seção do corpo no tipo de objeto é uma parte opcional. Se nenhum membro estiver presente, um tipo de objeto não conterá nenhuma parte do corpo.
Criar objeto em Oracle
Um tipo de objeto não pode ser criado no nível do subprograma. Eles podem ser criados apenas no nível do esquema. Uma vez definido o tipo de objeto no esquema, o mesmo pode ser utilizado em subprogramas. O tipo de objeto pode ser criado usando 'CREATE TYPE'. O corpo do tipo só pode ser criado após a criação do seu tipo de objeto.
CREATE TYPE<object_type_name> AS OBJECT ( <attribute_l><datatype>, . . ); / CREATE TYPE BODY<object_type_name> AS OBJECT ( MEMBER[PROCEDURE|FUNCTION]<member_name> IS <declarative section> BEGIN <execution part> END; . . ); /
Explicação da sintaxe:
- A sintaxe acima mostra a criação de 'OBJECT' com atributos e 'OBJECT-BODY' com métodos.
- Os métodos também podem estar sobrecarregados no corpo do objeto.
Inicialização de declaração do tipo de objeto
Como outros componentes em PL/SQL, os tipos de objetos também precisam ser declarados antes de serem usados no programa.
Uma vez criado o tipo de objeto, ele pode ser usado na seção declarativa do subprograma para declarar uma variável desse tipo de objeto.
Sempre que qualquer variável for declarada no subprograma como tipo de objeto, em tempo de execução uma nova instância do tipo de objeto será criada, e esta instância recém-criada poderá ser referenciada ao nome da variável. Dessa forma, um único tipo de objeto pode armazenar vários valores em diferentes instâncias.
DECLARE <variable_name> <object_type_name>; BEGIN . . END; /
Explicação da sintaxe:
- A sintaxe acima mostra a declaração de uma variável como tipo de objeto na seção declarativa.
Uma vez que a variável é declarada como um tipo de objeto em um subprograma, ela será atomicamente nula, ou seja, todo o objeto será nulo. Ele precisa ser inicializado com valores para usá-los no programa. Eles podem ser inicializados usando construtores.
Construtores são o método implícito de um objeto que pode ser referido com o mesmo nome do tipo de objeto. A sintaxe abaixo mostra a inicialização do tipo de objeto.
DECLARE <variable_name> <object_type_name>; BEGIN <variable_name>:=<object_type_name>(); END; /
Explicação da sintaxe:
- A sintaxe acima mostra a inicialização da instância do tipo de objeto com um valor nulo.
- Agora, o objeto em si não é nulo porque foi inicializado, mas os atributos dentro do objeto serão nulos porque não atribuímos nenhum valor a esses atributos.
Construtores
Construtores são o método implícito de um objeto que pode ser referido com o mesmo nome do tipo de objeto. Sempre que o objeto for referido pela primeira vez, este construtor será chamado implicitamente.
Também podemos inicializar os objetos usando este construtor. O construtor pode ser definido explicitamente definindo o membro no tipo de objeto body com o mesmo nome do tipo de objeto.
Exemplo 1: No exemplo a seguir usaremos o tipo de objeto member para inserir o registro na tabela emp com valores ('RRR', 1005, 20000, 1000) e ('PPP', 1006, 20000, 1001). Assim que os dados forem inseridos, iremos exibi-los usando o tipo de objeto membro. Também usaremos o construtor explícito para preencher o ID do gerente por padrão com o valor 1001 para o segundo registro.
Vamos executá-lo nas etapas abaixo.
- Step1:
- Criar tipo de objeto
- Corpo do tipo de objeto
- Passo 2: Criação de um bloco anônimo para chamar o tipo de objeto criado por meio do construtor implícito para emp_no 1005.
- Etapa 3: Criação de um bloco anônimo para chamar o tipo de objeto criado por meio do construtor explícito para emp_no 1006.
Passo 1) Criar tipo de objeto e corpo do tipo de objeto
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER, p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records); /
CREATE OR REPLACE TYPE BODY emp_object AS CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2, p_salary NUMBER) RETURN SELF AS RESULT IS BEGIN Dbms_output.put_line(’Constructor fired..'); SELF.emp_no:=p_emp_no;| SELF.emp_name:=p_emp_name; SELF.salary:=p_salary; SELF.managerial:=1001; RETURN; END: MEMBER PROCEDURE insert_records IS BEGIN INSERT INTO emp VALUES(emp_noemp_name,salary,manager); END MEMBER PROCEDURE display_records IS BEGIN Dbms_output.put_line('Employee Name:'||emp_name); Dbms_output.put_line('Employee Number:'||emp_no); Dbms_output.put_line('Salary':'||salary); Dbms_output.put_line('Manager:'||manager); END: END: /
Explicação do código
- Linha de código 1-9: Criando o tipo de objeto 'emp_object' com 4 atributos e 3 membros. Contém a definição de construtores com apenas 3 parâmetros. (O construtor implícito real conterá o número de parâmetros igual ao número de atributos presentes no tipo de objeto)
- Linha de código 10: Criando o corpo do tipo.
- Linha de código 11-21: Definindo o construtor explícito. Atribuir o valor do parâmetro aos atributos e atribuir o valor ao atributo 'manager' com o valor padrão '1001'.
- Linha de código 22-26: Definindo o membro 'insert_records' no qual os valores dos atributos são inseridos na tabela 'emp'.
- Linha de código 27-34: Definindo o membro 'display_records' no qual são exibidos os valores dos atributos do tipo de objeto.
saída
Tipo criado
Digite corpo criado
Passo 2) Criando bloco anônimo para chamar o tipo de objeto criado através do construtor implícito para emp_no 1005
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1005,’RRR',20000,1000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END;
Explicação do código
- Linha de código 37-45: Inserindo os registros usando o construtor implícito. A chamada ao construtor contém o número real de valores de atributos.
- Linha de código 38: Declara guru_emp_det como tipo de objeto 'emp_object'.
- Linha de código 41: A instrução 'guru_emp_det.display_records' chamada de função membro 'diplay_records' e os valores dos atributos são exibidos
- Linha de código 42: A instrução 'guru_emp_det.insert_records' chama a função membro 'insert_records' e os valores dos atributos são inseridos na tabela.
saída
Nome do funcionário: RRR
Número do funcionário: 1005
Salário: 20000
Gerente: 1000
Passo 3) Criando bloco anônimo para chamar o tipo de objeto criado através do construtor explícito para emp_no 1006
DECLARE guru_emp_det emp_object; BEGIN guru_emp_det:=emp_object(1006,'PPP',20000); guru_emp_det.display_records; guru_emp_det.insert_records; COMMIT; END; /
saída
Employee Name:PPP Employee Number:1006 Salary:20000 Manager:1001
Explicação do código:
- Linha de código 46-53: Inserindo os registros usando o construtor explícito.
- Linha de código 46: Declara guru_emp_det como tipo de objeto 'emp_object'.
- Linha de código 50: A instrução 'guru_emp_det.display_records' chamada de função membro 'display_records' e os valores dos atributos são exibidos
- Linha de código 51: A instrução 'guru_emp_det.insert_records' chama a função membro 'insert_records' e os valores dos atributos são inseridos na tabela.
Herança no tipo de objeto
A propriedade de herança permite que o tipo de subobjeto acesse todos os atributos e membros do tipo de superobjeto ou tipo de objeto pai.
O tipo de subobjeto é chamado de tipo de objeto herdado e o tipo de superobjeto é chamado de tipo de objeto pai. A sintaxe abaixo mostra como criar o tipo de objeto pai e herdado.
CREATE TYPE <object_type_name_parent> AS OBJECT ( <attribute_l><datatype>, . . )NOT FINAL; /
Explicação da sintaxe:
- A sintaxe acima mostra a criação do tipo SUPER.
CREATE TYPE<object_type_name_sub>UNDER<object_type_name_parent> ( <attribute_l><datatype>, . ); /
Explicação da sintaxe:
- A sintaxe acima mostra a criação do tipo SUB. Ele contém todos os membros e atributos do tipo de objeto pai.
Exemplo1: No exemplo abaixo, usaremos a propriedade de herança para inserir o registro com o ID do gerente como '1002' para o registro seguinte ('RRR', 1007, 20000).
Vamos executar o programa acima nas seguintes etapas
- Passo 1: Crie o tipo SUPER.
- Passo 2: Crie o tipo e o corpo do SUB.
- Passo 3: Criando um bloco anônimo para chamar o tipo SUB.
Passo 1) Crie o tipo SUPER ou o tipo Pai.
CREATE TYPE emp_object AS OBJECT( emp_no NUMBER, emp_name VARCHAR2(50), salary NUMBER, manager NUMBER, CONSTRUCTOR FUNCTION emp_object(p_emp_no NUMBER,p_emp_name VARCHAR2(50), p_salary NUMBER)RETURN SELF AS RESULT), MEMBER PROCEDURE insert_records, MEMBER PROCEDURE display_records)NOT FINAL; /
Explicação do código:
- Linha de código 1-9: Criando o tipo de objeto 'emp_object' com 4 atributos e 3 membros. Contém a definição de construtores com apenas 3 parâmetros. Foi declarado como 'NÃO FINAL', portanto é do tipo pai.
Passo 2) Crie o tipo SUB no tipo SUPER.
CREATE OR REPLACE TYPE sub_emp_object UNDER emp_object (default_manager NUMBER,MEMBER PROCEDURE insert_default_mgr); / CREATE OR REPLACE TYPE BODY sub_emp_object AS MEMBER PROCEDURE insert_default_mgr IS BEGIN INSERT INTO emp VALUES(emp_no,emp_name:salary,manager): END; END; /
Explicação do código:
- Linha de código 10-13: Criando o sub_emp_object como tipo herdado com um atributo adicional 'default_manager' e declaração de procedimento de membro.
- Linha de código 14: Criando o corpo para o tipo de objeto herdado.
- Linha de código 16-21: Definindo o procedimento membro que está inserindo os registros na tabela “emp” com os valores do tipo de objeto 'SUPER', exceto o valor do gerenciador. Para o valor do gerenciador, está usando o tipo 'default_manager' do tipo 'SUB'.
Passo 3) Criando bloco anônimo para chamar o tipo SUB
DECLARE guru_emp_det sub_emp_object; BEGIN guru_emp_det:= sub_emp_object(1007,'RRR',20000,1000,1002); guru_emp_det.insert_default_mgr; COMMIT; END; /
Explicação do código:
- Linha de código 25: Declarando 'guru_emp_det' como tipo 'sub_emp_object'.
- Linha de código 27: inicializando o objeto com o construtor implícito. O construtor possui 5 parâmetros (4 atributos do tipo PARENT e 2 atributos do tipo SUB). O último parâmetro (1002) define o valor do atributo default_manager
- Linha de código 28: Chamando o membro 'insert_default_mgr' para inserir os registros com o id do gerenciador padrão passado no construtor.
Igualdade de objetos PL/SQL
A instância do objeto que pertence aos mesmos objetos pode ser comparada quanto à igualdade. Para isso, precisamos ter o método especial no tipo de objeto denominado método 'ORDER'.
Este método 'ORDER' deve ser a função que retorna o tipo numérico. São necessários dois parâmetros como entrada (primeiro parâmetro: id da instância do objeto próprio, segundo parâmetro: id de outra instância do objeto).
O id das duas instâncias do objeto é comparado e o resultado é retornado em forma numérica.
- O valor positivo representa que a instância do objeto SELF é maior que outra instância.
- O valor negativo representa que a instância do objeto SELF é menor que outra instância.
- Zero representa que a instância do objeto SELF é igual a outra instância.
- Se alguma das instâncias for nula, esta função retornará nulo.
CREATE TYPE BODY<object_type_name_ 1>AS OBJECT ( ORDER MEMBER FUNCTION match(<parameter> object_type_name_ 1) RETURN INTEGER IS BEGIN IF <attribute_name>parameter <attribute_name>THEN RETURN -1; --any negative number will do ELSIF id>c.id THEN RETURN 1; —any positive number will do ELSE RETURN 0; END IF; END; . . ); /
Explicação da sintaxe:
- A sintaxe acima mostra a função ORDER que precisa ser incluída no corpo do tipo para verificação de igualdade.
- O parâmetro para esta função deve ser uma instância do mesmo tipo de objeto.
- A função acima pode ser chamada como “obj_instance_1.match(obj_instance_2)” e esta expressão retornará o valor numérico conforme mostrado, onde obj_instance_1 e obj_instance_2 são a instância de object_type_name.
Example1: No exemplo a seguir veremos como comparar dois objetos. Vamos criar duas instâncias e comparar o atributo 'salário' entre elas. Faremos duas etapas.
- Etapa 1: Criando o tipo e o corpo do objeto.
- Etapa 2: Criando o bloco anônimo para chamar a comparação da instância do objeto.
Passo 1) Criando o tipo e corpo do objeto.
CREATE TYPE emp_object_equality AS OBJECT( salary NUMBER, ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER); /
CREATE TYPE BODY emp_object_equality AS ORDER MEMBER FUNCTION equals(c emp_object_equality)RETURN INTEGER IS BEGIN IF salary<c.salary THEN RETURN -1; ELSIF salary>c.salary THEN RETURN 1; ELSE RETURN 0; END IF: END; END; /
Explicação do código:
- Linha de código 1-4: Criando o tipo de objeto 'emp_object_equality' com 1 atributo e 1 membro.
- Linha de código 6-16: Definindo a função ORDER que compara o atributo 'salário' da instância SELF e o tipo de instância do parâmetro. Retorna negativo se o salário SELF for menor ou positivo se o salário SELF for maior e 0 se os salários forem iguais.
Saída de código:
Tipo criado
Passo 2) Criando o bloco anônimo para chamar a comparação da instância do objeto.
DECLARE l_obj_l emp_object_equality; l_obj_2 emp_object_equality; BEGIN l_obj_l:=emp_object_equality(15000); l_obj_2:=emp_object_equality(17000); IF l_obj_1.equalS(l_obj_2)>0 THEN Dbms_output.put_line(’Salary of first instance is greater’): ELSIF l_obj_l.equalS(l_obj_2)<0 THEN Dbms_output.put_line(’Salary of second instance is greater’); ELSE Dbms_output.put_line(’Salaries are equal’); END IF; END; /
saída
Salary of second instance is greater
Explicação do código:
- Linha de código 20: Declarando o l_obj_1 do tipo emp_object_equality.
- Linha de código 21: Declarando o l_obj_2 do tipo emp_object_equality.
- Linha de código 23: Inicializando l_obj_1 com valor de salário como '15000'
- Linha de código 24: Inicializando l_obj_1 com valor de salário como '17000'
- Linha de código 25-33: imprime a mensagem com base no número de retorno da função ORDER.
Resumo
Neste capítulo, vimos o tipo de objeto e suas propriedades. Também discutimos sobre Construtores, Membros, Atributos, Herança e Igualdade em objetos PL/SQL.