将 plpgsql var 与游标语句查询连接时出错
Error while concatenating plpgsql var with query on cursor statement
我在尝试在第二个中连接 var sch 时遇到错误 For:
ERROR: syntax error in or next a "||"
SQL state: 42601
Character: 1151
有谁知道如何解决这个连接问题?
CREATE OR REPLACE FUNCTION generate_mallet_input2() RETURNS VOID AS $$
DECLARE
sch name;
r record;
BEGIN
FOR sch IN
select schema_name from information_schema.schemata where schema_name not in ('test','summary','public','pg_toast','pg_temp_1','pg_toast_temp_1','pg_catalog','information_schema')
LOOP
FOR r IN SELECT rp.id as id,g.classified as classif, concat(rp.summary,rp.description,string_agg(c.message, '. ')) as mess
FROM sch.report rp
INNER JOIN || sch || .report_comment rc ON rp.id=rc.report_id
INNER JOIN || sch || .comment c ON rc.comments_generatedid=c.generatedid
INNER JOIN || sch || .gold_set g ON rp.id=g.key
WHERE g.classified = any (values('BUG'),('IMPROVEMENT'),('REFACTORING'))
GROUP BY g.classified,rp.summary,rp.description,rp.id
LOOP
IF r.classif = 'BUG' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/BUG/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
ELSIF r.classif = 'IMPROVEMENT' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/IMPROVEMENT/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
ELSIF r.classif = 'REFACTORING' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/REFACTORING/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
END IF;
END LOOP;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT;
不确定,现在没有安装 PostgreSQL,但看起来你必须做一些类似的事情
INNER JOIN || sch || '.report_comment' rc ON rp.id=rc.report_id
它将 .report_comment 部分视为变量或其他方式。
如果整个脚本必须动态生成,取决于sch
值
FOR r IN SELECT rp.id as id,g.classified as classif, concat(rp.summary,rp.description,string_agg(c.message, '. ')) as mess
FROM sch.report rp
INNER JOIN || sch || .report_comment rc ON rp.id=rc.report_id
INNER JOIN || sch || .comment c ON rc.comments_generatedid=c.generatedid
INNER JOIN || sch || .gold_set g ON rp.id=g.key
WHERE g.classified = any (values('BUG'),('IMPROVEMENT'),('REFACTORING'))
GROUP BY g.classified,rp.summary,rp.description,rp.id
那么你应该以动态方式调用它 - execute blabla
,就像你在上面的代码中所做的那样。
您不能动态更改嵌入式 SQL 的架构。任何与数据库相关的标识符都必须是常量。如果你有一些现代的 PostgreSQL(可能高于 9.2,适用于 9.4),你可以更改搜索路径:
create schema s1;
create schema s2;
create table s1.t1(a int);
create table s2.t1(a int);
insert into s1.t1 values(10);
insert into s2.t1 values(20);
do $$
declare r record;
begin
for i in 1..2 loop
perform set_config('search_path', 's'||i, true);
for r in select * from t1 loop
raise notice '%', r;
end loop;
end loop;
end; $$;
如果此代码不起作用,您必须使用 动态 SQL - FOR IN EXECUTE
语句。
我在尝试在第二个中连接 var sch 时遇到错误 For:
ERROR: syntax error in or next a "||" SQL state: 42601 Character: 1151
有谁知道如何解决这个连接问题?
CREATE OR REPLACE FUNCTION generate_mallet_input2() RETURNS VOID AS $$
DECLARE
sch name;
r record;
BEGIN
FOR sch IN
select schema_name from information_schema.schemata where schema_name not in ('test','summary','public','pg_toast','pg_temp_1','pg_toast_temp_1','pg_catalog','information_schema')
LOOP
FOR r IN SELECT rp.id as id,g.classified as classif, concat(rp.summary,rp.description,string_agg(c.message, '. ')) as mess
FROM sch.report rp
INNER JOIN || sch || .report_comment rc ON rp.id=rc.report_id
INNER JOIN || sch || .comment c ON rc.comments_generatedid=c.generatedid
INNER JOIN || sch || .gold_set g ON rp.id=g.key
WHERE g.classified = any (values('BUG'),('IMPROVEMENT'),('REFACTORING'))
GROUP BY g.classified,rp.summary,rp.description,rp.id
LOOP
IF r.classif = 'BUG' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/BUG/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
ELSIF r.classif = 'IMPROVEMENT' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/IMPROVEMENT/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
ELSIF r.classif = 'REFACTORING' THEN
EXECUTE 'Copy( Values('|| r.mess || ') ) To ''/tmp/csv-temp/REFACTORING/' || quote_ident(sch) || '-' || r.id || '.txt '' With DELIMITER '' '' ';
END IF;
END LOOP;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql STRICT;
不确定,现在没有安装 PostgreSQL,但看起来你必须做一些类似的事情
INNER JOIN || sch || '.report_comment' rc ON rp.id=rc.report_id
它将 .report_comment 部分视为变量或其他方式。
如果整个脚本必须动态生成,取决于sch
值
FOR r IN SELECT rp.id as id,g.classified as classif, concat(rp.summary,rp.description,string_agg(c.message, '. ')) as mess
FROM sch.report rp
INNER JOIN || sch || .report_comment rc ON rp.id=rc.report_id
INNER JOIN || sch || .comment c ON rc.comments_generatedid=c.generatedid
INNER JOIN || sch || .gold_set g ON rp.id=g.key
WHERE g.classified = any (values('BUG'),('IMPROVEMENT'),('REFACTORING'))
GROUP BY g.classified,rp.summary,rp.description,rp.id
那么你应该以动态方式调用它 - execute blabla
,就像你在上面的代码中所做的那样。
您不能动态更改嵌入式 SQL 的架构。任何与数据库相关的标识符都必须是常量。如果你有一些现代的 PostgreSQL(可能高于 9.2,适用于 9.4),你可以更改搜索路径:
create schema s1;
create schema s2;
create table s1.t1(a int);
create table s2.t1(a int);
insert into s1.t1 values(10);
insert into s2.t1 values(20);
do $$
declare r record;
begin
for i in 1..2 loop
perform set_config('search_path', 's'||i, true);
for r in select * from t1 loop
raise notice '%', r;
end loop;
end loop;
end; $$;
如果此代码不起作用,您必须使用 动态 SQL - FOR IN EXECUTE
语句。