IDIOMA SQL vs IDIOMA plpgsql en funciones PostgreSQL

Resuelto asked hace 10 años • 3 respuestas

Soy muy nuevo en el desarrollo de bases de datos , así que tengo algunas dudas con respecto a mi siguiente ejemplo:

Función f1() - lenguaje sql

 create or replace function f1(istr  varchar)
 returns text as $$ 
 select 'hello! '::varchar || istr;
 $$ language sql;

Función f2() - lenguaje plpgsql

 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin select 'hello! '::varchar || istr; end;
 $$ language plpgsql;
  • Ambas funciones se pueden llamar como select f1('world')o select f2('world').

  • Si llamo select f1('world')la salida será:

     `hello! world`
    
  • Y salida para select f2('world'):

    ERROR: la consulta no tiene destino para los datos del resultado. SUGERENCIA: Si desea descartar los resultados de SELECT, utilice PERFORM en su lugar. CONTEXTO: Función PL/pgSQL f11 (carácter variable) línea 2 en la instrucción SQL ********** Error **********

  • Deseo saber la diferencia y en qué situaciones debo usar language sqlo language plpgsql.

Cualquier enlace útil o respuesta sobre funciones será muy apreciado.

 avatar Jul 15 '14 17:07
Aceptado

funciones SQL

... son la mejor opción:

  • Para consultas escalares simples . No hay mucho que planificar, es mejor ahorrarse los gastos generales.

  • Para llamadas únicas (o muy pocas) por sesión . No hay nada que ganar con el almacenamiento en caché del plan a través de declaraciones preparadas que PL/pgSQL tiene para ofrecer. Vea abajo.

  • Si normalmente se llaman en el contexto de consultas más importantes y son lo suficientemente simples como para incluirlos en línea .

  • Por falta de experiencia con algún lenguaje procedimental como PL/pgSQL. Muchos conocen bien SQL y eso es todo lo que necesitan para las funciones SQL. Pocos pueden decir lo mismo de PL/pgSQL. (Aunque es bastante simple).

  • Un código un poco más corto. Sin bloque por encima.

Funciones PL/pgSQL

... son la mejor opción:

  • Cuando necesite elementos de procedimiento o variables que no estén disponibles en las funciones SQL, obviamente.

  • Para cualquier tipo de SQL dinámico , donde se crean EXECUTEdeclaraciones dinámicamente. Se necesita especial cuidado para evitar la inyección SQL. Más detalles:

    • Funciones de Postgres frente a consultas preparadas
  • Cuando tiene cálculos que se pueden reutilizar en varios lugares y un CTE no se puede estirar para ese propósito. En una función SQL no tiene variables y se vería obligado a calcular repetidamente o escribir en una tabla. Esta respuesta relacionada en dba.SE tiene ejemplos de código en paralelo para resolver el mismo problema usando una función SQL/una función plpgsql/una consulta con CTE:

    • Cómo pasar un parámetro a una función

    Las tareas son algo más caras que en otros lenguajes procedimentales. Adapte un estilo de programación que no utilice más asignaciones de las necesarias.

  • Cuando una función no se puede insertar y se llama repetidamente. A diferencia de las funciones SQL, los planes de consulta se pueden almacenar en caché para todas las declaraciones SQL dentro de funciones PL/pgSQL ; se tratan como declaraciones preparadas , el plan se almacena en caché para llamadas repetidas dentro de la misma sesión (si Postgres espera que el plan almacenado en caché (genérico) funcione mejor que volver a planificar cada vez. Esa es la razón por la cual las funciones PL/pgSQL suelen ser más rápidas después las primeras dos llamadas en tales casos.

    Aquí hay un hilo sobre pgsql-rendimiento que analiza algunos de estos elementos:

    • Re: ¿Las funciones pl/pgsql superan a las de sql?
  • Cuando necesitas detectar errores .

  • Para funciones de disparo .

  • Al incluir declaraciones DDL que cambian objetos o alteran catálogos del sistema de cualquier manera relevante para comandos posteriores, porque todas las declaraciones en las funciones SQL se analizan a la vez mientras que las funciones PL/pgSQL planifican y ejecutan cada declaración secuencialmente (como una declaración preparada). Ver:

    • ¿Por qué las funciones PL/pgSQL pueden tener efectos secundarios, mientras que las funciones SQL no?

Considere también:

  • Rendimiento del procedimiento almacenado de PostgreSQL

Para regresar realmente desde una función PL/pgSQL, podrías escribir:

CREATE FUNCTION f2(istr varchar)
  RETURNS text AS
$func$
BEGIN
   RETURN 'hello! ';  -- defaults to type text anyway
END
$func$ LANGUAGE plpgsql;

Hay otras formas:

  • ¿Puedo hacer que una función plpgsql devuelva un número entero sin usar una variable?
  • El manual sobre "Regresar de una función"
Erwin Brandstetter avatar Jul 16 '2014 03:07 Erwin Brandstetter

PL/PgSQL es un lenguaje de procedimientos específico de PostgreSQL basado en SQL . Tiene bucles, variables, manejo de errores/excepciones, etc. No todo SQL es PL/PgSQL válido; como descubrió, por ejemplo, no puede usarlo SELECTsin INTOo RETURN QUERY. PL/PgSQL también se puede utilizar en DObloques para procedimientos de una sola vez.

sqlLas funciones solo pueden usar SQL puro, pero a menudo son más eficientes y más simples de escribir porque no necesita un BEGIN ... END;bloque, etc. Las funciones SQL pueden estar integradas, lo cual no es cierto para PL/PgSQL.

La gente suele utilizar PL/PgSQL cuando SQL simple sería suficiente, porque están acostumbrados a pensar de forma procesal. En la mayoría de los casos, cuando cree que necesita PL/PgSQL, probablemente en realidad no lo necesita. Los CTE recursivos, las consultas laterales, etc. generalmente satisfacen la mayoría de las necesidades.

Para más información... consulte el manual.

Craig Ringer avatar Jul 15 '2014 10:07 Craig Ringer

simplemente haga la consulta de selección que escribió dentro de la función como valor devuelto:

 create  or replace function f2(istr  varchar)
 returns text as $$ 
 begin return(select 'hello! '::varchar || istr); end;
 $$ language plpgsql;
ZORRO_BLANCO avatar Nov 14 '2018 14:11 ZORRO_BLANCO