我是 PostgreSQL 的初学者。尝试在这里循环我传递的值:
companyregistration
只需拨打 companyRegistrationValidator
函数调用:
SELECT companyregistration(
'876786576544',
'TraderAnalytics',
'[email protected],
'@kjvfhjh88976',
ARRAY['86578657865','Natali','Vladimirov','[email protected]', '+@jvfhjh88976'],
ARRAY [['Maks','Burkov'],['Yan','Burkov']],
'Netherlands',
'Company');
[2018-10-28 18:29:15] [42804] ERROR: FOREACH expression must yield an array, not type text [2018-10-28 18:29:15] Where: PL/pgSQL function companyregistrationvalidator(character varying,character varying,character varying,character varying,text[],text[],character varying) line 28 at FOREACH over array
函数定义:
CREATE OR REPLACE FUNCTION companyRegistrationValidator (company_id VARCHAR, comp_name VARCHAR, comp_email VARCHAR, comp_password VARCHAR, employees text[], creators text[], country VARCHAR)
RETURNS BOOLEAN AS $$
DECLARE
checked BOOLEAN := FALSE ;
r_id VARCHAR; r_name VARCHAR; r_email VARCHAR; r_password VARCHAR; r_country VARCHAR;
cr_counter INTEGER = 0; em_counter INTEGER = 0; c_ar_length INTEGER = 0; e_ar_length INTEGER = 0;
ar_index text; creator text; val text;
BEGIN
SELECT id_r , email_r , password_r , country_r , firstname_r INTO r_id , r_email , r_password, r_country , r_name FROM regex;
c_ar_length := cardinality(creators);
e_ar_length := cardinality(employees);
FOREACH val IN ARRAY employees LOOP
IF val ~ r_id THEN em_counter := +1;
ELSEIF val ~ r_name THEN em_counter := +1;
ELSEIF val ~ r_email THEN em_counter := +1;
ELSEIF val ~ r_password THEN em_counter := +1;
END IF;
END LOOP;
FOREACH creator IN ARRAY creators LOOP
FOREACH ar_index IN ARRAY creator LOOP
IF ar_index ~ r_name THEN cr_counter := +1;
END IF;
END LOOP;
END LOOP;
IF cr_counter = c_ar_length AND em_counter = e_ar_length AND company_id ~ r_id AND comp_name ~ r_name AND comp_email ~ r_email AND comp_password ~ r_password AND country ~ r_country
THEN checked := TRUE;
END IF;
RETURN checked;
END;
$$ LANGUAGE plpgsql;
我的代码有什么错误?
这个嵌套循环结构非常适合您引用的错误:
FOREACH creator IN ARRAY creators LOOP
FOREACH ar_index IN ARRAY creator LOOP
IF ar_index ~ r_name THEN cr_counter := +1;
END IF;
END LOOP;
END LOOP;
外循环中的循环变量
creator
定义为类型text
,这样就可以了。但是你不能像你尝试的那样通过 creator
嵌套另一个循环 - 也不需要这样做。无论数组维数有多少,都会按存储顺序访问元素。
因此,要循环遍历所有基本元素,无论数组维度如何,您所需要的只是:
FOREACH creator IN ARRAY creators LOOP
IF creator ~ r_name THEN cr_counter := cr_counter + 1;
END IF;
END LOOP;
另请注意,
cr_counter := +1
不会像您似乎正在尝试的那样增加cr_counter
。只需重复分配 1
即可。我将其替换为实际递增的表达式。
然而,就像经常发生的那样,除非数组非常小,否则基于集合的方法会(快得多)。喜欢:
SELECT INTO cr_counter
count(*) FILTER (WHERE _creator ~ r_name)::int
FROM unnest(creators) _creator;
(您确定需要正则表达式运算符
~
吗?)
我在下面遇到了同样的错误:
错误:FOREACH 表达式必须生成一个数组,而不是类型字符变化
当我尝试使用 FOREACH 语句迭代数组时,如下所示:
DO $$
DECLARE
temp VARCHAR;
arr VARCHAR := ARRAY['a','b','c','d'];
BEGIN
FOREACH temp SLICE 0 IN ARRAY arr LOOP
RAISE INFO '%', temp;
END LOOP;
END
$$;
所以,我将
[]
设置在VARCHAR
之后,如下所示:
DO $$
DECLARE
temp VARCHAR;
arr VARCHAR[] := ARRAY['a','b','c','d'];
BEGIN -- ↑↑ Here
FOREACH temp SLICE 0 IN ARRAY arr LOOP
RAISE INFO '%', temp;
END LOOP;
END
$$;
然后,我可以使用 FOREACH 语句 迭代数组,如下所示:
INFO: a
INFO: b
INFO: c
INFO: d
DO