甲骨文 SQL: select regexp_substr, "into clause is expected"
Oracle SQL: select regexp_substr, "into clause is expected"
我正在尝试使用 regexp_substr 拆分以逗号分隔的字符串,但出现 "into clause is expected" 错误:
select regexp_substr(improv,'[^,]+', 1, level) from dual
connect by regexp_substr(improv, '[^,]+', 1, level) is not null;
"improv"是一个varchar(100)变量,而我运行上面的语句在一个PLSQL块里面。
在PL/SQL你需要输出SQl查询INTO
一个变量。
但是,由于此查询将生成多行,您可能希望使用 BULK COLLECT INTO
而不仅仅是 INTO
并将输出放入用户定义的集合或 VARRAY
(其中 SYS.ODCIVARCHAR2LIST
是一个例子。注意:您不能将 MEMBER OF
运算符与 VARRAY
一起使用:
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
BEGIN
SELECT regexp_substr(improv,'[^,]+', 1, level)
BULK COLLECT INTO list_of_improvs
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null;
END;
/
更新:
回应您的评论 - 您可以像这样使用它(虽然不清楚您要实现什么,所以我只是将您的代码放入一个片段中,而没有试图弄清楚您打算做什么) :
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
BEGIN
SELECT regexp_substr(improv,'[^,]+', 1, level)
BULK COLLECT INTO list_of_improvs
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null;
FOR i IN 1 .. list_of_improvs.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( improvs(i) );
END LOOP;
update line_cap
set cap_up = list_of_improvs(1)
where id IN ( SELECT Column_Value
FROM TABLE( list_of_improvs ) );
END;
/
您不能将 IN
直接用于集合或 VARRAY,需要在嵌套查询中使用 TABLE()
集合表达式来获取值。
如果您使用的是用户定义的 SQL 集合 - 即使用如下语句定义:
CREATE TYPE StringList IS TABLE OF VARCHAR2(4000);
然后可以使用MEMBER OF
运算符:
DECLARE
list_of_improvs StringList;
BEGIN
-- as above
update line_cap
set cap_up = list_of_improvs(1)
where id MEMBER OF list_of_improvs;
END;
/
但是您不能将 MEMBER OF
运算符与 VARRAY
一起使用(如 SYS.ODCIVARCHAR2LIST
)。
但是,您不需要 PL/SQL(并消除 PL/SQL 和 SQL 执行范围之间昂贵的上下文切换)并且可以只使用 MERGE
语句类似于:
MERGE INTO line_cap dst
USING (
SELECT MIN( value ) KEEP ( DENSE_RANK FIRST ORDER BY ROWNUM ) OVER () AS first_value,
value
FROM (
SELECT regexp_substr(improv,'[^,]+', 1, level) AS value
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null
)
) src
ON ( src.value = dst.id )
WHEN MATCHED THEN
UPDATE
SET cap_up = first_value;
我把它放在这里而不是对 MT0 的回答的评论,因为评论不适用于格式化。无论如何,这是一个完整的示例,它使用 MT0 的答案来加载一个数组,然后循环遍历它以显示内容。这将向您展示如何访问列表的内容。感谢 MT0 为您提供原始问题的答案。
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
i number;
BEGIN
SELECT regexp_substr('1,2,3,4,5','(.*?)(,|$)', 1, level, NULL, 1)
BULK COLLECT INTO list_of_improvs
FROM dual
CONNECT BY level <= regexp_count('1,2,3,4,5', ',') + 1;
i := list_of_improvs.FIRST; -- Get first element of array
while i is not null LOOP
DBMS_OUTPUT.PUT_LINE(list_of_improvs(i));
i := list_of_improvs.NEXT(i); -- Get next element of array
END LOOP;
END;
/
我正在尝试使用 regexp_substr 拆分以逗号分隔的字符串,但出现 "into clause is expected" 错误:
select regexp_substr(improv,'[^,]+', 1, level) from dual
connect by regexp_substr(improv, '[^,]+', 1, level) is not null;
"improv"是一个varchar(100)变量,而我运行上面的语句在一个PLSQL块里面。
在PL/SQL你需要输出SQl查询INTO
一个变量。
但是,由于此查询将生成多行,您可能希望使用 BULK COLLECT INTO
而不仅仅是 INTO
并将输出放入用户定义的集合或 VARRAY
(其中 SYS.ODCIVARCHAR2LIST
是一个例子。注意:您不能将 MEMBER OF
运算符与 VARRAY
一起使用:
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
BEGIN
SELECT regexp_substr(improv,'[^,]+', 1, level)
BULK COLLECT INTO list_of_improvs
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null;
END;
/
更新:
回应您的评论 - 您可以像这样使用它(虽然不清楚您要实现什么,所以我只是将您的代码放入一个片段中,而没有试图弄清楚您打算做什么) :
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
BEGIN
SELECT regexp_substr(improv,'[^,]+', 1, level)
BULK COLLECT INTO list_of_improvs
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null;
FOR i IN 1 .. list_of_improvs.COUNT LOOP
DBMS_OUTPUT.PUT_LINE( improvs(i) );
END LOOP;
update line_cap
set cap_up = list_of_improvs(1)
where id IN ( SELECT Column_Value
FROM TABLE( list_of_improvs ) );
END;
/
您不能将 IN
直接用于集合或 VARRAY,需要在嵌套查询中使用 TABLE()
集合表达式来获取值。
如果您使用的是用户定义的 SQL 集合 - 即使用如下语句定义:
CREATE TYPE StringList IS TABLE OF VARCHAR2(4000);
然后可以使用MEMBER OF
运算符:
DECLARE
list_of_improvs StringList;
BEGIN
-- as above
update line_cap
set cap_up = list_of_improvs(1)
where id MEMBER OF list_of_improvs;
END;
/
但是您不能将 MEMBER OF
运算符与 VARRAY
一起使用(如 SYS.ODCIVARCHAR2LIST
)。
但是,您不需要 PL/SQL(并消除 PL/SQL 和 SQL 执行范围之间昂贵的上下文切换)并且可以只使用 MERGE
语句类似于:
MERGE INTO line_cap dst
USING (
SELECT MIN( value ) KEEP ( DENSE_RANK FIRST ORDER BY ROWNUM ) OVER () AS first_value,
value
FROM (
SELECT regexp_substr(improv,'[^,]+', 1, level) AS value
FROM DUAL
CONNECT BY regexp_substr(improv, '[^,]+', 1, level) is not null
)
) src
ON ( src.value = dst.id )
WHEN MATCHED THEN
UPDATE
SET cap_up = first_value;
我把它放在这里而不是对 MT0 的回答的评论,因为评论不适用于格式化。无论如何,这是一个完整的示例,它使用 MT0 的答案来加载一个数组,然后循环遍历它以显示内容。这将向您展示如何访问列表的内容。感谢 MT0 为您提供原始问题的答案。
DECLARE
list_of_improvs SYS.ODCIVARCHAR2LIST;
i number;
BEGIN
SELECT regexp_substr('1,2,3,4,5','(.*?)(,|$)', 1, level, NULL, 1)
BULK COLLECT INTO list_of_improvs
FROM dual
CONNECT BY level <= regexp_count('1,2,3,4,5', ',') + 1;
i := list_of_improvs.FIRST; -- Get first element of array
while i is not null LOOP
DBMS_OUTPUT.PUT_LINE(list_of_improvs(i));
i := list_of_improvs.NEXT(i); -- Get next element of array
END LOOP;
END;
/