关于postgresql:plpgsql嵌套函数上的游标

plpgsql cursor on unnest function

我有一个plpgsql函数,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
DO
$$
DECLARE
  c_id c.id%TYPE;  
  j_text c.j_options%TYPE;
  j_option VARCHAR;
  c1 c%ROWTYPE;

BEGIN
  CREATE TYPE my_row_type AS (c2 TEXT);
  FOR
    --c1 in select c.j_options, c.id from c c
    c1 IN SELECT * FROM c
    loop
      c_id = c1.id;
        FOR
         c2 IN SELECT * FROM  unnest(string_to_array(c1.j_options,', '))
         loop
        raise notice 'Value: %, %', c_id, c2.j_options;
         END loop;  

    END loop;
END
$$ LANGUAGE plpgsql;

我的问题是这一行:

1
c2 IN SELECT * FROM  unnest(string_to_array(c1.j_options,', '))

我运行的示例查询,例如:

1
SELECT unnest(string_to_array('1.0, 1.2',', '));

返回2行:

1
2
1. 1.0
2. 1.2

我需要遍历这两行,但是不确定此unnest语句的返回类型应该是什么,或者如何在声明部分中声明它。

运行脚本时出现的错误:

1
2
3
4
ERROR:  loop variable OF loop OVER ROWS must be a record OR ROW variable OR

list OF scalar VARIABLES
LINE 18:          c2 IN SELECT * FROM  unnest(string_to_array(c1.j_...

从下面的答案中,我得到以下错误

1
2
3
4
5
ERROR:  FUNCTION string_to_array(bytea, UNKNOWN) does NOT exist
LINE 1: SELECT FROM  unnest(string_to_array(c1.j_options,', '))
                            ^
HINT:  No FUNCTION matches the given name AND argument types. You might need TO ADD explicit TYPE casts.
QUERY:  SELECT FROM  unnest(string_to_array(c1.j_options,', '))

我不明白为什么这在脚本中不起作用。它识别出c1.j_optionsbytea

我修改的脚本位是:

1
2
3
4
5
FOR c2 IN
   SELECT FROM unnest(string_to_array(c1.j_options,', '))
loop
   raise notice '%', c2;
END loop;


错误消息为"错误:函数string_to_array(bytea,未知)不存在"。 BYtea类型不是文本,而是二进制值,并且对于该类型,未定义函数string_to_array。没有将默认值从字节转换为文本。很难说什么是解决方案,因为bytea可以容纳任何东西。如果有一些文本,则应该使用类型"文本",而不是bytea。


根据string_to_array函数签名,它返回文本数组(text[]),因此c2应该是textvarchar

1
2
3
4
5
6
7
8
do LANGUAGE plpgsql $$
DECLARE
  c VARCHAR;
BEGIN
  FOR c IN SELECT unnest(string_to_array('1.0, 1.2', ', ')) loop
    raise notice '%', c;
  END loop;
END; $$;

还有一种特殊的循环类型可以直接遍历数组元素:

1
2
3
4
5
6
7
8
do LANGUAGE plpgsql $$
DECLARE
  c VARCHAR;
BEGIN
  foreach c IN array string_to_array('1.0, 1.2', ', ') loop
    raise notice '%', c;
  END loop;
END; $$;