Estoy tratando de crear una función que hace referencia a una tabla temporal en PostgreSQL 8.4. Basado en mi investigación parece la mejor manera de hacer esto es utilizar el EXECUTE comando a ejecutar mi consulta de una cadena definida.

Por desgracia me estoy poniendo un extraño error de sintaxis cuando se trata de crear la función.

Mi actual definición de la función es como sigue:

CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
  EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
$$ LANGUAGE SQL;

El error que estoy recibiendo es:

ERROR:  syntax error at or near "'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table'"
LINE 2:   execute 'INSERT INTO table1 (col1, col2, col3) SELECT col1...

Parece que me sale el mismo error, independientemente de lo que realmente está en el literal de cadena.

Mis preguntas son, 1) ¿cuál es la sintaxis correcta para el uso de la EJECUCIÓN de la característica, y 2) existe una mejor manera de escribir una función como esta, que hace referencia a una tabla temporal?

InformationsquelleAutor Mike Deck | 2011-07-28

3 Comentarios

  1. 12

    Yo creo que tu problema es el idioma que está utilizando. EJECUTAR en el lenguaje SQL:

    EXECUTE se utiliza para ejecutar previamente un comunicado. Desde declaraciones preparadas sólo existen para la duración de una sesión, el comunicado debe haber sido creado por un PREPARE instrucción ejecutada anteriormente en la sesión actual.

    no es el mismo que EJECUTAR en PL/pgSQL:

    A veces usted va a querer para generar dinámicas de comandos dentro de su PL/pgSQL funciones, es decir, los comandos que se involucran diferentes tablas o diferentes tipos de datos cada vez que se ejecutan. PL/pgSQL normal de los intentos de caché de planes de comandos (como se discutió en la Sección 39.10.2) no funcionará en tales escenarios. Para controlar este tipo de problema, el EXECUTE es:

    EXECUTE command-string [ INTO [STRICT] target ] [ USING expression [, ... ] ];

    Estás usando el SQL EXECUTE (que se ejecuta una instrucción preparada) cuando desee utilizar el PL/pgSQL EJECUTAR (que ejecuta una cadena como SQL).

    Intente esto:

    CREATE OR REPLACE FUNCTION example() RETURNS void AS $$
    BEGIN
        EXECUTE 'INSERT INTO table1 (col1, col2, col3) SELECT col1, col2, col3 from temp_table';
    END;
    $$ LANGUAGE PLPGSQL;

    O, otro ejemplo, que parece más cerca de lo que parecen estar tratando de hacer:

    create or replace function example(tname text) returns void as $$
    begin
        execute 'insert into ' || tname || ' (name) values(''pancakes'')';
    end;
    $$ language plpgsql;

    Que se inserte 'pancakes' en la tabla que se pasa en la tname argumento a la función.

  2. 0

    EJECUTAR se utiliza para ejecutar las sentencias preparadas y sólo espera una declaración preparada nombre como argumento.

    Si usted está tratando de ejecutar una instrucción SQL (como en tu ejemplo), simplemente se debe incluir en el cuerpo de la función.

    Comprobar la manual para obtener más información acerca de «Lenguaje de Consulta (SQL) Funciones».

    OTOH si usted está tratando de crear una PL/pgSQL función (que no es lo que has demostrado en tu pregunta), entonces usted necesita para convertir su función de ser un PL/pgSQL función.

    • Yo simplemente no puede incluir la consulta en el cuerpo de la función, ya que hace referencia a una tabla temporal que no existe en el momento en que se crea la función. Es la única manera de evitar que el uso de PL/pgSQL función?
  3. 0

    Es un ejemplo probado por mí donde yo lo uso ejecutar para ejecutar un select y poner el resultado en un cursor.

    1. Crear la tabla:

    create table people (
      nickname varchar(9),
      name varchar(12),
      second_name varchar(12),
      country varchar(30)
      );

    2. Crear la función:

    CREATE OR REPLACE FUNCTION fun_find_people (col_name text, col_value varchar)
    RETURNS void AS
    $BODY$
    DECLARE
        local_cursor_p refcursor;
        row_from_people RECORD;
    
    BEGIN
        open local_cursor_p FOR
            EXECUTE 'select * from people where '|| col_name || ' LIKE ''' || col_value || '%'' ';
    
        raise notice 'col_name: %',col_name;
        raise notice 'col_value: %',col_value;
    
        LOOP
            FETCH local_cursor_p INTO row_from_people; EXIT WHEN NOT FOUND;
    
            raise notice 'row_from_people.nickname: %',  row_from_people.nickname ;
            raise notice 'row_from_people.name: %', row_from_people.name ;
            raise notice 'row_from_people.country: %', row_from_people.country;
        END LOOP;
    END;
    $BODY$ LANGUAGE 'plpgsql'

    3. Ejecutar la función

    select fun_find_people('name', 'Cristian');
    select fun_find_people('country', 'Chile');

Dejar respuesta

Please enter your comment!
Please enter your name here