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

Como passo um parâmetro de tabela para esta função?


Tudo testado no Postgres 9.4 .

O Postgres tem alguns pontos fracos na sintaxe para lidar com tipos ROW. Você não pode converter diretamente de uma tabela (alias):
SELECT w::waypoint FROM waypoints w;

A solução está a apenas um passo de distância:decomponha a linha em uma subconsulta, então a conversão funciona. Dessa forma, os valores das colunas são decompostos e agrupados diretamente no novo tipo, sem converter para text e volta. Não há necessidade de listar todas as colunas individualmente e você também não precisa criar uma conversão personalizada:
SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;

Ou mais curto:
SELECT w.*::waypoint FROM (TABLE waypoints) w;

Ou mais curto, ainda:
SELECT w::waypoint FROM (TABLE waypoints) w;

SQL Fiddle

Isso é mais curto e mais rápido, em um teste rápido com 30 mil linhas e tipos simples 10 vezes mais rápido do que transmitir para text e volta. Se você tiver (grande) jsonb colunas ou qualquer tipo complexo (conversão cara de/para text ), a diferença será muito maior, ainda.

Mais importante, você não precisa outro tipo de composição personalizada (ROW). Toda tabela já tem sua linha definida como tipo automaticamente. Basta usar o tipo existente waypoints em vez de waypoint (se tudo for possível). Então tudo que você precisa é:
SELECT w FROM waypoints w;

Ou, para o seu exemplo:
SELECT everything(t) FROM temp t;  -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t;  -- using type waypoint

Apartes:
  • Uma tabela não tem "argumentos", mas colunas.

  • Você não passando um parâmetro table parameter to this function , mas sim um valor de linha . É assim que você passa uma tabela por nome:

    Você não pode "passar uma tabela inteira" como parâmetro diretamente no Postgres, não existem variáveis ​​de tabela. Você usaria um cursor ou uma tabela temporária para isso.

Função


Sua função tem uma declaração de tipo inválida e é desnecessariamente complexa. Eu duvido seriamente que você queira criar uma visão:
CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
BEGIN
   RETURN QUERY
   SELECT ...
END
$func$ LANGUAGE plpgsql;

text array não é uma sintaxe válida, usando text[] em vez de declarar uma matriz de text .

Em vez disso, não use o nome da tabela / tipo waypoints como o nome do parâmetro da função, que abre espaço para erros confusos.

Ou apenas use uma função SQL simples se o seu caso for tão simples quanto demonstrado:
CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
   SELECT ...
$func$ LANGUAGE sql;

Não cite o nome do idioma. É um identificador.