我有一个光标,它指向一个SELECT,但是这个选择是动态生成的。我想在声明后分配声明。 我做了一个工作的例子,另一个例子不工作。这是仅打印一些数据的简单示例。 这是表格:
CREATE TABLE public.my_columns (
id serial NOT NULL,
"name" varchar(30) NOT NULL,
/* Keys */
CONSTRAINT my_columns_pkey
PRIMARY KEY (id)
) WITH (
OIDS = FALSE
);
CREATE INDEX my_columns_index01
ON public.my_columns
("name");
INSERT INTO public.my_columns
("name")
VALUES
('name1'),
('name2'),
('name3'),
('name4'),
('name5'),
('name6');
这是函数(我已将工作代码和代码无效):
CREATE OR REPLACE FUNCTION public.dynamic_table
(
)
RETURNS text AS $$
DECLARE
v_sql_dynamic varchar;
--NOT WORKING:
--db_c CURSOR IS (v_sql_dynamic::varchar);
--WORKING:
db_c CURSOR IS (SELECT id, name from public.my_columns);
db_rec RECORD;
BEGIN
v_sql_dynamic := 'SELECT id, name from public.my_columns';
FOR db_rec IN db_c LOOP
RAISE NOTICE 'NAME: %', db_rec.name;
END LOOP;
RETURN 'OK';
EXCEPTION WHEN others THEN
RETURN 'Error: ' || SQLERRM::text || ' ' || SQLSTATE::text;
END;
$$ LANGUAGE plpgsql;
有什么想法吗?
谢谢。
答案 0 :(得分:7)
你真的需要显式游标吗?如果需要迭代动态SQL,则可以使用FOR IN EXECUTE
。它是用于动态SQL的隐式(内部)游标的循环
FOR db_rec IN EXECUTE v_sql_dynamic
LOOP
..
END LOOP
documentation - OPEN FOR EXECUTE
中描述了更复杂的解决方案:
do $$
declare r refcursor; rec record;
begin
open r for execute 'select * from pg_class';
fetch next from r into rec;
while found
loop
raise notice '%', rec;
fetch next from r into rec;
end loop;
close r;
end $$;
使用这种光标,您无法使用FOR IN