PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

O nome da coluna PL/pgSQL é igual ao da variável


Assumindo id_pracownika é a PRIMARY KEY da mesa. Ou pelo menos definido UNIQUE . (Se não for NOT NULL , NULL é um caso de canto.)

SELECT ou INSERT


Sua função é outra implementação de "SELECT ou INSERT" - uma variante do UPSERT problema, que é mais complexo em face da carga de gravação simultânea do que pode parecer. Ver:
  • O SELECT ou INSERT está em uma função propensa a condições de corrida?

Com UPSERT no Postgres 9.5 ou posterior


No Postgres 9.5 ou posterior use UPSERT (INSERT ... ON CONFLICT ... ) Detalhes no Wiki do Postgres. Essa nova sintaxe faz um trabalho limpo :
CREATE OR REPLACE FUNCTION hire(
        _id_pracownika integer
      , _imie varchar
      , _nazwisko varchar
      , _miasto varchar
      , _pensja real)
  RETURNS text
  LANGUAGE plpgsql AS
$func$
BEGIN
   INSERT INTO pracownicy
          ( id_pracownika, imie, nazwisko, miasto, pensja)
   VALUES (_id_pracownika,_imie,_nazwisko,_miasto,_pensja);
   ON     CONFLICT DO NOTHING
   RETURNING 'OK';

   IF NOT FOUND THEN
      RETURN 'JUZ ISTNIEJE';
   END IF;
END
$func$;

Nomes de coluna qualificados de tabela para desambiguar quando necessário. (Você também pode prefixar os parâmetros da função com o nome da função, mas isso fica complicado, facilmente.)
Mas os nomes das colunas na lista de destino de um INSERT pode não ser qualificado para mesa. (Nunca ambíguo de qualquer maneira.)

Melhor evitar tais ambiguidades a priori, pois é menos propenso a erros. Alguns (inclusive eu) gostam de fazer isso prefixando todos os parâmetros e variáveis ​​da função com um sublinhado.

Se você positivamente precisa um nome de coluna como nome de parâmetro de função também, uma maneira de evitar colisões de nomes é usar um ALIAS dentro da função. Um dos raros casos em que ALIAS é realmente útil.

Ou faça referência aos parâmetros da função por posição ordinal:$1 para id_pracownika nesse caso.

Se tudo mais falhar, você pode decidir o que tem precedência definindo #variable_conflict . Ver:
  • Conflito de nomenclatura entre parâmetro de função e resultado de JOIN com cláusula USING

Há mais:

  • Existem complexidades no RETURNING cláusula em um UPSERT. Ver:
    • Como usar RETURNING com ON CONFLICT no PostgreSQL?

  • Literais de string (constantes de texto) devem ser colocados entre aspas simples:'OK', não "OK" . Ver:
    • Inserir texto com aspas simples no PostgreSQL

  • A atribuição de variáveis ​​é comparativamente mais cara do que em outras linguagens de programação. Mantenha as atribuições no mínimo para melhor desempenho em plpgsql. Faça o máximo possível em instruções SQL diretamente.

  • VOLATILE COST 100 são decoradores padrão para funções. Não há necessidade de soletrar aqueles.

Sem UPSERT no Postgres 9.4 ou anterior

...
   IF EXISTS (SELECT FROM pracownicy p
             WHERE  p.id_pracownika = hire.id_pracownika) THEN
      RETURN 'JUZ ISTNIEJE';
   ELSE
      INSERT INTO pracownicy(id_pracownika,imie,nazwisko,miasto,pensja)
      VALUES (hire.id_pracownika,hire.imie,hire.nazwisko,hire.miasto,hire.pensja);
    
      RETURN 'OK';
   END IF;
...

Em um EXISTS expressão, o SELECT lista não importa. SELECT id_pracownika , SELECT 1 , ou mesmo SELECT 1/0 - tudo o mesmo. Basta usar um SELECT vazio Lista. Apenas a existência de qualquer linha de qualificação importa. Ver:
  • O que é mais fácil de ler nas subconsultas EXISTS?