Em artigos anteriores, abordamos os perigos de usar palavras-chave SQL e nomes cíclicos ao nomear variáveis em rotinas armazenadas no PostgreSQL. Mas os desafios da nomeação no PL/pgSQL não param por aí. Há um terceiro problema que pode complicar ainda mais o seu código: a ambiguidade quando as variáveis de uma função têm o mesmo nome que as colunas do seu banco de dados.

Ilustrando o Problema com um Exemplo Prático

Suponha que temos a seguinte tabela employees:

CREATE TABLE employees (
  employee_id INTEGER,
  name TEXT,
  salary INTEGER
);

E agora você está criando uma função PL/pgSQL que calcula um aumento salarial, e você escolhe chamar sua variável de salary, igual à coluna da tabela:

CREATE OR REPLACE FUNCTION raise_salary(employee_id INTEGER, increase INTEGER) 
RETURNS VOID AS $$
DECLARE
  salary INTEGER;
BEGIN
  SELECT salary + increase INTO salary 
  FROM employees WHERE employee_id = employee_id;

  UPDATE employees SET salary = salary
  WHERE employee_id = employee_id;
END;
$$ LANGUAGE plpgsql;

Parece correto, certo? No entanto, essa função não funcionará como esperado. O problema é que o PostgreSQL não consegue distinguir entre a variável salary e a coluna salary da tabela employees. O mesmo vale para employee_id.

Se você tentar executar essa função, a atualização não afetará a coluna salary da tabela, como pretendido. Em vez disso, ela alterará apenas a variável salary na função. Além disso, a cláusula WHERE se torna ambígua porque não está claro a qual employee_id ela se refere: o parâmetro ou a coluna?

Como Resolver Variáveis Ambíguas

Uma das melhores maneiras de evitar essa confusão é nunca usar o mesmo nome para uma variável de função e uma coluna de tabela. Por exemplo, poderíamos chamar a variável de new_salary em vez de salary:

CREATE OR REPLACE FUNCTION raise_salary(p_employee_id INTEGER, increase INTEGER) 
RETURNS VOID AS $$
DECLARE
  new_salary INTEGER;
BEGIN
  SELECT salary + increase INTO new_salary 
  FROM employees WHERE employee_id = p_employee_id;

  UPDATE employees SET salary = new_salary
  WHERE employee_id = p_employee_id;
END;
$$ LANGUAGE plpgsql;

Agora, está claro que a variável new_salary contém o novo salário, e p_employee_id é o parâmetro passado para a função. Isso resolve a ambiguidade.

Sobre o autor

Pós graduado em Gestão de Projetos em Tecnologia da Informação pela UNIASSELVI.
Esposo e Pai, curto atividades ao ar livre (Bike, SUP, Natação, Caminhar, Brincar no campo)

Atua com Banco de Dados Oracle desde de 2007. Atualmente é DBA Senior na FLUIDATA Serviços em Banco de dados (www.fluidata.com.br)

Principais atividade Banco de dados:

Implementação, migração, gerenciamento e suporte a produtos Oracle (8i, 9i, 10g, 11g, 12c, 18c, 19c RAC), multiplataforma;
Implementação, migração, gerenciamento e suporte a produtos Microsoft SQL Server (2008 - 2019);
Implementação, migração, gerenciamento e suporte a produtos PostgreSQL (9.3 - 14);
Monitoramento de ambientes 24×7;
Backup e Recovery;
Performance e Tuning;
Alta disponibilidade (HA);
EM database/grid/cloud control;
Conversão de databases;
Standby database / Oracle Data Guard;

Certificações:

Oracle Cloud Infrastructure 2019 Certified Architect AssociateOracle Cloud Infrastructure 2019 Certified Architect Associate
Oracle Database 12c Administrator Certified ProfessionalOracle Database 12c Administrator Certified Professional
Exadata Database Machine Models X2-2 and X2-8 Technology Support SpecialistExadata Database Machine Models X2-2 and X2-8 Technology Support Specialist
Oracle Database 11g Support SpecialistOracle Database 11g Support Specialist
OCP 11g - Oracle Certified Professional AdministratorOCP 11g - Oracle Certified Professional Administrator
OPN Certified Specialist 10g - PartnerNetwork Certified SpecialistOPN Certified Specialist 10g - PartnerNetwork Certified Specialist
Oracle Database 10g Real Applications Clusters AdministratorCertified ExpertOracle Database 10g Real Applications Clusters AdministratorCertified Expert
Oracle Database 10g: Managing Oracle on Linux Certified ExpertOracle Database 10g: Managing Oracle on Linux Certified Expert
OCP 10g - Oracle Certified Professional AdministratorOCP 10g - Oracle Certified Professional Administrator

Principais atividades DEVOPS:

PHP
ASP.net
C#
Docker
Golang
C++
Delphi
Python
HTML5
JavaScript

Você também pode gostar: