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

Passar vários conjuntos ou matrizes de valores para uma função


Você pode conseguir isso com uma função SQL simples. O recurso principal é a função generate_subscripts() :
CREATE OR REPLACE FUNCTION f_attendance(_arr2d int[])
  RETURNS SETOF attendance AS
$func$
   SELECT a.*
   FROM   generate_subscripts($1, 1) i
   JOIN   attendance a ON a.class   = $1[i][1]
                      AND a.section = $1[i][2]
$func$  LANGUAGE ROWS 10 sql STABLE;

Ligar:
SELECT * FROM f_attendance(ARRAY[[1,1],[2,2]]);

Ou o mesmo com um array literal - o que é mais conveniente em alguns contextos, especialmente com declarações preparadas:
SELECT * FROM f_attendance('{{1,1},{2,2}}');

A função sempre espera uma matriz 2D. Mesmo se você passar um único par, aninhe-o:
SELECT * FROM f_attendance('{{1,1}}');

Auditoria de sua implementação


  1. Você fez a função VOLATILE , mas pode ser STABLE . Por documentação:

    Devido a esse comportamento de instantâneo, uma função contendo apenas SELECT comandos podem ser marcados com segurança como STABLE .

    Relacionado:
    • Como passar um parâmetro para uma função de data

  2. Você também usa LANGUAGE plpgsql em vez de sql , o que faz sentido se você executar a função várias vezes na mesma sessão. Mas então você também deve torná-lo STABLE ou você perde esse potencial benefício de desempenho. O manual mais uma vez:

    STABLE e IMMUTABLE as funções usam um instantâneo estabelecido no início da consulta de chamada, enquanto as funções VOLATILE obtêm um instantâneo no início de cada consulta que executam.

  3. Seu EXPLAIN a saída mostra uma Varredura somente de índice , não uma varredura sequencial como você suspeita em seu comentário.

  4. Há também uma etapa de classificação em seu EXPLAIN saída que não corresponde ao código que você mostra. Tem certeza de que copiou o EXPLAIN correto saída? Como você conseguiu isso de qualquer maneira? As funções PL/pgSQL são caixas pretas para EXPLAIN . Você usou auto_explain ? Detalhes:
    • Plano de consulta Postgres de uma invocação de UDF escrita em pgpsql

  5. O planejador de consultas do Postgres não tem ideia de quantos elementos de array o parâmetro passado terá, então é difícil planejar a consulta e pode ser padrão para uma varredura sequencial (dependendo de mais fatores). Você pode ajudar declarando o número esperado de linhas. Se você normalmente não tiver mais de 10 itens, adicione ROWS 10 como eu fiz agora acima. E teste novamente.