如何从 plpgsql 函数中作为参数接收的数组循环?
How to loop from an array received as a parameter in plpgsql function?
我对 pgplsql 有点陌生,到目前为止,我必须创建一个函数来循环接收作为函数接收的数组。
该函数的主要思想是将新记录插入到 table 中,该 table 将接收到的数组中包含的每个 ID 映射为新格式的 ID,格式取决于接收到的第二个参数和 return table "idsTable".
问题是,当我尝试创建函数时,它向我发送了一个错误:
错误:FOREACH 的循环变量必须是已知变量或变量列表
第 38 行:FOREACH objectid IN ARRAY idsList LOOP
我不确定是否必须声明 objectid 变量,因为在我看到的示例中他们没有声明。
到目前为止我有这个:
CREATE OR REPLACE FUNCTION createId(idsList varchar[], objectType varchar)
RETURNS TABLE(original_id varchar, new_id char) as
$$
BEGIN
IF LOWER(objectType) = 'global' THEN
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'GID'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
ELSE
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'ORG'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
END IF;
END;
$$ LANGUAGE plpgsql;
有什么地方可能出错的想法吗?
编辑:我还没有添加 idsTable 是 returned 的部分。
不相关,但是:你真的不需要一个循环。你可以通过只写一次 INSERT
来简化函数。您还忘记了 return 函数中的某些内容。因为它被声明为 returns table
,所以需要:
CREATE OR REPLACE FUNCTION createid(idslist varchar[], objecttype varchar)
RETURNS TABLE(original_id varchar, new_id varchar) as
$$
declare
l_prefix text;
BEGIN
IF LOWER(objectType) = 'global' THEN
l_prefix := 'GID';
ELSE
l_prefix := 'ORG';
END IF;
RETURN QUERY --<< return the result of the insert
INSERT INTO idstable(original_id, new_id)
select t.x, l_prefix||nextval('mapSquema.globalid')::TEXT
from unnest(idslist) as t(x)
returning *
END;
$$ LANGUAGE plpgsql;
我对 pgplsql 有点陌生,到目前为止,我必须创建一个函数来循环接收作为函数接收的数组。
该函数的主要思想是将新记录插入到 table 中,该 table 将接收到的数组中包含的每个 ID 映射为新格式的 ID,格式取决于接收到的第二个参数和 return table "idsTable".
问题是,当我尝试创建函数时,它向我发送了一个错误:
错误:FOREACH 的循环变量必须是已知变量或变量列表 第 38 行:FOREACH objectid IN ARRAY idsList LOOP
我不确定是否必须声明 objectid 变量,因为在我看到的示例中他们没有声明。
到目前为止我有这个:
CREATE OR REPLACE FUNCTION createId(idsList varchar[], objectType varchar)
RETURNS TABLE(original_id varchar, new_id char) as
$$
BEGIN
IF LOWER(objectType) = 'global' THEN
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'GID'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
ELSE
FOREACH objectid IN ARRAY idsList LOOP
INSERT INTO idsTable(original_id, new_id)
VALUES(objectid, 'ORG'||nextval('mapSquema.globalid')::TEXT);
END LOOP;
END IF;
END;
$$ LANGUAGE plpgsql;
有什么地方可能出错的想法吗?
编辑:我还没有添加 idsTable 是 returned 的部分。
不相关,但是:你真的不需要一个循环。你可以通过只写一次 INSERT
来简化函数。您还忘记了 return 函数中的某些内容。因为它被声明为 returns table
,所以需要:
CREATE OR REPLACE FUNCTION createid(idslist varchar[], objecttype varchar)
RETURNS TABLE(original_id varchar, new_id varchar) as
$$
declare
l_prefix text;
BEGIN
IF LOWER(objectType) = 'global' THEN
l_prefix := 'GID';
ELSE
l_prefix := 'ORG';
END IF;
RETURN QUERY --<< return the result of the insert
INSERT INTO idstable(original_id, new_id)
select t.x, l_prefix||nextval('mapSquema.globalid')::TEXT
from unnest(idslist) as t(x)
returning *
END;
$$ LANGUAGE plpgsql;