sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo paso un parámetro de tabla a esta función?

Todo probado en Postgres 9.4 .

Postgres tiene algunos puntos débiles en la sintaxis para manejar tipos ROW. No puedes enviar desde una tabla (alias) directamente:

SELECT w::waypoint FROM waypoints w;

La solución está a solo un paso de distancia:descomponga la fila en una subconsulta, luego el reparto funciona. De esta manera, los valores de columna se descomponen y se envuelven directamente en el nuevo tipo, sin convertirlos en text y vuelta No es necesario enumerar todas las columnas individualmente y tampoco es necesario crear una conversión personalizada:

SELECT (w.*)::waypoint FROM (SELECT * FROM waypoints) w;

O más corto:

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

O más corto, todavía:

SELECT w::waypoint FROM (TABLE waypoints) w;

SQL Fiddle

Eso es más corto y más rápido, en una prueba rápida con 30 000 filas y tipos simples 10 veces más rápido que enviar a text y vuelta Si tiene (grande) jsonb columnas o cualquier tipo complejo (conversión costosa a/desde text ), la diferencia será aún mucho mayor.

Más importante aún, no necesita otro tipo compuesto personalizado (ROW). Cada tabla ya tiene su fila definida como tipo automáticamente. Simplemente use el tipo existente waypoints en lugar de waypoint (si es posible). Entonces todo lo que necesitas es:

SELECT w FROM waypoints w;

O, para su ejemplo:

SELECT everything(t) FROM temp t;  -- using type waypoints
SELECT everything(t::waypoint) FROM (TABLE temp) t;  -- using type waypoint

Apartes:

  • Una tabla no tiene "argumentos" sino columnas.
  • Tu no pasando un table parameter to this function , sino un valor de fila . Así es como pasas una mesa por nombre:

    No puede "pasar una tabla completa" como parámetro directamente en Postgres, no hay variables de tabla. Usarías un cursor o una tabla temporal para eso.

Función

Su función tiene una declaración de tipo no válida y es innecesariamente compleja. Dudo seriamente que quieras crear una vista:

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 no es una sintaxis válida, usando text[] en lugar de declarar una matriz de text .

En lugar de usar el nombre de tabla / tipo waypoints como nombre de parámetro de función, eso lo abre a errores confusos.

O simplemente use una función SQL simple si su caso es tan simple como se muestra:

CREATE FUNCTION everything(_wp waypoint)  -- or use type waypoints
  RETURNS TABLE(node int, xy text[]) AS
$func$
   SELECT ...
$func$ LANGUAGE sql;

No cite el nombre del idioma. Es un identificador.