Function PL/pgSQL代码的问题
我在plpgsql方面不是很有经验,所以我这里有两个问题 在Postgres中是否可以像在动态sql for plsql中那样使用游标?基本上,我不想在plsql中使用过程,所以我创建了一个游标,它将保存动态查询的输出,然后我在另一个查询中的循环中使用该值,以使我的输出显示在屏幕上。同样的事情,我正试图与博士后,但不能这样做。 在这种情况下,是否有可能避免创建永久性功能来完成此任务? 以下是我运行良好的oracle脚本:Function PL/pgSQL代码的问题,function,postgresql,cursor,plpgsql,dynamic-sql,Function,Postgresql,Cursor,Plpgsql,Dynamic Sql,我在plpgsql方面不是很有经验,所以我这里有两个问题 在Postgres中是否可以像在动态sql for plsql中那样使用游标?基本上,我不想在plsql中使用过程,所以我创建了一个游标,它将保存动态查询的输出,然后我在另一个查询中的循环中使用该值,以使我的输出显示在屏幕上。同样的事情,我正试图与博士后,但不能这样做。 在这种情况下,是否有可能避免创建永久性功能来完成此任务? 以下是我运行良好的oracle脚本: DECLARE CURSOR cur_tables IS S
DECLARE
CURSOR cur_tables IS
SELECT NAME,
'SELECT PROPERTY_VALUE FROM '
|| USERNAME
|| '.P_PROPERTY WHERE PROPERTY_NAME = ''VERSION'''
AS dsql
FROM CB_DATASOURCE
WHERE (UPPER(USERNAME) LIKE 'NAV_PS_%' or UPPER(USERNAME) LIKE 'CBPS_%' or UPPER(USERNAME) LIKE 'DEFAULTPS');
CURR_VERSION VARCHAR2(1000);
BEGIN
FOR r_tables IN cur_tables LOOP
begin
EXECUTE IMMEDIATE r_tables.dsql INTO CURR_VERSION;
DBMS_OUTPUT.put_line(r_tables.NAME || ': ' || CURR_VERSION);
exception
when others then
DBMS_OUTPUT.put_line(r_tables.NAME || ' no table');
end;
END LOOP;
END;
/
这是我的postgres函数,我无法让它工作,但最终我想避免使用永久函数
create or replace function upgrade_version() returns setof record as $$
declare
r record;
loopy record;
isql text;
CURR_VERSION text;
begin
for r in SELECT 'SELECT PROPERTY_VALUE FROM '
|| USERNAME
|| '.P_PROPERTY WHERE PROPERTY_NAME = ''VERSION'''
AS dsql
FROM CB_DATASOURCE
WHERE (UPPER(USERNAME) LIKE 'NAV_PS_%' or UPPER(USERNAME) LIKE 'CBPS_%' or UPPER(USERNAME) LIKE 'DEFAULTPS') loop
isql := r.dsql;
EXECUTE isql INTO CURR_VERSION;
RETURN next loopy;
end loop;
return;
end;
$$ language 'plpgsql';
我非常感谢您在这方面的任何意见。您可以通过使用DO$$$脚本避免创建永久函数: 但是,我不清楚如何避免完全使用PL/pgSQL代码,因为您是基于另一个查询的内容定义游标的。您正在Oracle中使用PL/SQL代码;为什么在PostgreSQL中不需要过程代码 如果您对游标有偏好,您当然可以在PL/pgSQL函数中使用OPEN CURSOR FOR EXECUTE,但不能使用Oracle中的相同结构;在PL/pgSQL中,不能将游标声明为字符串替换。这仅在打开时执行:
除了为每个用户提供一个EAV设置表不是一个很好的设计之外…您似乎要尝试的应该是: 要点 您不能从DO语句返回,但可以发出通知等。 似乎非常适合您,因为您最终希望避免使用永久函数。 请注意,DO语句的默认过程语言仍然是plpgsql 在Postgres中,不带引号的标识符被转换为小写,而Oracle是大写的 要捕获循环中的异常,需要将主体包装在单独的块中 您需要清理动态构建的SQL字符串中的标识符,以免易受SQL注入和其他非标准名称问题的影响。您的Oracle代码也缺少。 为此,我正在使用带有%I的格式。更多信息: 将WHERE子句缩短为 您知道uu是类似模式中的占位符字符吗?对于文字\,将其转义为:\ \
过程语言的名称为。RDBMS的名称是。至少你可以自己发现。请提出一个适当的问题,不要害怕。谢谢你的意见。下一次,我会尝试提出一个体面的问题。旁白:不要在语言plpgsql中引用语言名称。它是一个标识符,不是字符串。暂时可以容忍,但在未来的版本中可能会消失。
DO
$do$
DECLARE
r record;
curr_version text;
BEGIN
FOR r IN
SELECT name, format($$
SELECT property_value
FROM %I.p_property
WHERE property_name = 'VERSION'$$, username) AS dsql
FROM cb_datasource
WHERE upper(username) LIKE ANY ('{NAV_PS_%, CBPS_%, DEFAULTPS}')
LOOP
BEGIN
EXECUTE r.dsql INTO curr_version;
RAISE NOTICE '%: %', r.name, curr_version;
EXCEPTION WHEN OTHERS THEN
RAISE NOTICE '%: no table', r.name;
END;
END LOOP;
END
$do$