【发布时间】:2014-08-31 19:56:06
【问题描述】:
我制作了一个小 pl/pgsql 脚本来重命名一些序列(添加前缀)并将它们的架构设置为“公共”。但是我不明白为什么我的“ELSE”指令在循环中只执行一次,这是不合逻辑的,因为我有很多行的“nspname”值不是“docuprocess”:
CREATE OR REPLACE FUNCTION move_schemas_to_public(target_schemas text[]) RETURNS integer AS $procedure$
DECLARE
rec RECORD;
sql text;
newname text;
nbreq integer := 0;
tabsize integer := array_length(target_schemas, 1);
i integer := 1;
debug boolean := false;
BEGIN
-- [...]
FOR rec in
select nspname, c.relname
from pg_class c
inner join pg_namespace ns
on (c.relnamespace = ns.oid)
where c.relkind = 'S'
and ns.nspname = any(target_schemas)
order by 1, 2
LOOP
IF rec.nspname = 'docuprocess' THEN
newname := rec.relname;
ELSE
-- Why these instructions are executed only once : -----
newname := rec.nspname||'_'||rec.relname;
sql := 'ALTER SEQUENCE '||rec.nspname||'.'||rec.relname||' RENAME TO '||newname;
RAISE NOTICE '%', sql;
IF debug is not true THEN
EXECUTE sql;
END IF;
nbreq := nbreq + 1;
--------------------------------------------------------
END IF;
sql := 'ALTER SEQUENCE '||rec.nspname||'.'||newname||' SET SCHEMA public';
RAISE NOTICE '%', sql;
IF debug is not true THEN
EXECUTE sql;
END IF;
nbreq := nbreq + 1;
END LOOP;
-- [...]
RETURN nbreq;
END;
select move_schemas_to_public(
-- schemas list
ARRAY[
'docufacture',
'docuprocess',
'formulaire',
'notification'
]
);
这是循环的 SQL 查询的结果:
[nspname];[relname]
"docufacture";"exportdoc_idexportdoc_seq"
"docufacture";"tableau_idcolonne_seq"
"docuprocess";"dp_action_champsdocuged_seq"
"docuprocess";"dp_action_commentaire_seq"
"docuprocess";"dp_action_docuged_seq"
"docuprocess";"dp_action_email_id_seq"
"docuprocess";"dp_action_formulaire_seq"
"docuprocess";"dp_action_id_seq"
"docuprocess";"dp_action_imprimer_id_seq"
"docuprocess";"dp_action_lancer_processus_id_seq"
"docuprocess";"dp_action_lancer_programme_id_seq"
"docuprocess";"dp_action_seq"
"docuprocess";"dp_action_transfert_fichier_id_seq"
"docuprocess";"dp_deroulement_etape_seq"
"docuprocess";"dp_deroulement_processus_seq"
"docuprocess";"dp_etape_seq"
"docuprocess";"dp_indisponibilite_seq"
"docuprocess";"dp_intervenant_seq"
"docuprocess";"dp_processus_seq"
"docuprocess";"dp_type_action_seq"
"formulaire";"champ_id_seq"
"formulaire";"fond_id_seq"
"formulaire";"formulaire_id_seq"
"formulaire";"modele_id_seq"
"notification";"notification_id_seq"
提前感谢您的宝贵帮助。
【问题讨论】:
-
我不确定你在问什么,但只有
LOOPbody 执行了多次,而IF/ELSE分支没有。 -
差不多就是这样。事实上,ELSE 分支中的指令只执行一次,然后循环中断。但是,我刚刚意识到,当我的“调试”变量固定为 true 时,指令会正确执行,就好像“执行”指令会中断循环一样。
-
我没有看到您的 Postgres 版本,应该始终包含在此类问题中。此外,更重要的是,您没有包含函数头,它是函数的组成部分。始终发布 complete 功能。标题可能是这里的关键部分。
-
我使用的是 8.4 版本(postgreSQL)。好的,我将编辑我的帖子以包含标题。
标签: sql postgresql plpgsql