我尝试使用 regexp_substr 分割逗号分隔的字符串,但出现“需要进入子句”错误:
select regexp_substr(improv,'[^,]+', 1, level) from dual
connect by regexp_substr(improv, '[^,]+', 1, level) is not null;
“improv”是一个 varchar(100) 变量,我在 PLSQL block 内运行上述语句。
最佳答案
在 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;
关于Oracle SQL : select regexp_substr, "into clause is expected",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48321845/