Вопрос:
У меня есть код курсора:
BEGIN; DECLARE cliente_cursor CURSOR FOR SELECT * FROM cliente;
Я хочу прочитать весь контент из таблицы “cliente”:
С помощью курсора. У меня есть код для SQL Server:
DECLARE cliente_cursor CURSOR FOR SELECT * FROM cliente OPEN cliente_cursor FETCH NEXT FROM cliente_cursor; While @@FETCH_STATUS=0 BEGIN FETCH NEXT FROM cliente_cursor; End CLOSE cliente_cursor DEALLOCATE cliente_cursor
И я хочу иметь рабочий код для PostgreSQL.
Я искал решение и видел, как люди обычно предлагают использовать функции. Интересно, есть ли какой-либо способ в этой СУБД PostgreSQL создать нечто похожее на код в SQL Server.
Я написал этот код:
CREATE OR REPLACE FUNCTION MyFunction() RETURNS setof cliente AS $$ DECLARE cursor_cliente CURSOR FOR SELECT * FROM cliente; rec cliente%ROWTYPE; BEGIN OPEN cursor_cliente; loop —fetch the table row inside the loop FETCH cursor_cliente INTO rec; — check if there is no record —exit from loop when record not found if not found then exit ; end if; end loop; RETURN; END; $$ LANGUAGE plpgsql;
Но когда я его запускаю, я получаю:
select MyFunction();
Любая идея, чем должен выглядеть код?
Любая помощь будет оценена очень много!
Ответ №1CREATE OR REPLACE FUNCTION foo() RETURNS setof cliente language plpgsql AS $$ DECLARE x cliente%rowtype ; BEGIN FOR x IN SELECT * FROM cliente loop RETURN NEXT x; END loop; END $$; SELECT * FROM foo();
это также можно сделать с помощью явного курсора.
CREATE OR REPLACE FUNCTION foo() RETURNS setof cliente language plpgsql as $$ DECLARE x cliente%rowtype ; cliente_cursor CURSOR FOR SELECT * FROM cliente; BEGIN FOR x IN cliente_cursor loop RETURN NEXT x; END loop; END $$; SELECT * FROM foo();
Функция будет сохраняться, чтобы либо дать ей полезное имя, либо сохранить его, либо отбросить его после завершения.
Если вы хотите, чтобы частное имя функции pg_temp.foo было приватным для вашей сессии.
Ответ №2
Если вы хотите просто вернуть все строки из запроса, используйте
RETURN QUERY SELECT …
и RETURNS TABLE(column1 type1, column2 type2,…) как тип функции.
Или для курсора:
RETURN QUERY FETCH ALL FROM cliente_cursor;
Чтобы сделать что-то с каждой строкой, используйте
FOR _record IN SELECT … LOOP <action1>; <action2>; … END LOOP;
из этого ответа.
Или для курсора:
FOR _record IN FETCH ALL FROM … LOOP <action1>; <action2>; … END LOOP;
для курсора.
Обратите внимание, что PostgreSQL имеет тип refcursor который позволяет вам использовать курсор по его текстовому имени. ИМХО это самый простой способ (подробнее)