如何转换逗号分隔的 varchar 以用于 pl/sql 中的“IN”子句?

Posted

技术标签:

【中文标题】如何转换逗号分隔的 varchar 以用于 pl/sql 中的“IN”子句?【英文标题】:how can I convert a comma separated varchar to be used in an "IN" Clause in pl/sql? 【发布时间】:2013-09-10 18:46:39 【问题描述】:

我有一个逗号分隔的 varchar,它将被动态确定。例如:

varchar cHighRank := (1,2,3,4,5,6,7,8)

我想在下面的 IN 子句中使用它,但系统会产生错误,因为 IN 子句仅适用于整数,例如:

if (rank in cHighRank) then
    --do the high rank...
elsif (rank in cLowRank) then
    -- do the low rank
end if; 

这个问题的基础是我必须将整数列表分成两半。它可能是 16、12 等。关键是我不知道它是动态的。示例:

16:低位:1,2,3,4,5,6,7,8 高位:9,10,11,12,13,14,15,16

我可以将我的动态值列表创建为 varchar,但它在 IN 子句中不起作用。

请帮忙。

谢谢,

【问题讨论】:

【参考方案1】:

不确定 mysql,但对于 Oracle,您可以使用正则表达式检查而不是 IN 子句,并在边界情况下进行一些工作

If REGEXP_LIKE(cHighRank, "rank" + ",") or REGEXP_LIKE(cHighRank, "," + "rank") or REGEXP_LIKE(cHighRank, "(" + "rank" + ")")

应该也可以使用 MySQL,只是我没有使用过那里的正则表达式

【讨论】:

【参考方案2】:

检查“项目”是否在逗号分隔列表中的一种方法是使用 INSTR 函数。

假设您在列表中没有任何额外的空格,一个技巧是添加前导和尾随逗号,例如

',1,2,3,'

然后搜索给定元素如',2,'

DECLARE 
   cHighRank VARCHAR2(100) := '1,2,3,4,5,6,7,8';

BEGIN
  IF INSTR( ','||cHighRank||',' , ','||rank||',' ) > 0 THEN
     -- matched
  END IF;

【讨论】:

【参考方案3】:
declare
  v_ranks constant varchar2(32767):= '1,2,3,4,5,6,7,8,9,10,11';
  -- number of ranks is number of commas + 1
  v_number_of_ranks constant number := regexp_count(v_ranks, ',') + 1;
  -- find the middle point
  -- you definition how to split odd number of ranks to hi/low might differ
  v_pos constant number := instr(v_ranks, ',', 1, v_number_of_ranks / 2);
begin
  -- split around the middle point
  dbms_output.put_line(' lowrank: ' || substr(v_ranks, 0, v_pos));
  dbms_output.put_line('highrank: ' || substr(v_ranks, v_pos + 1));
end;
/

输出:

 lowrank: 1,2,3,4,5,6,
highrank: 7,8,9,10,11

【讨论】:

【参考方案4】:
DECLARE
    Lowrank  VARCHAR2(30) := '1,2,3,4,5,6,7,8';
    HighRank VARCHAR2(30) := '9,10,11,12,13,14,15,16';
    rank     VARCHAR2(30) := '16';
BEGIN
    IF REPLACE(REGEXP_INSTR(Lowrank, ',0,1' || rank || ',0,1'), ',') > 0 THEN
        DBMS_OUTPUT.PUT_LINE('Lowrank');
    ELSIF REPLACE(REGEXP_INSTR(HighRank, ',0,1' || rank || ',0,1'), ',') > 0 THEN
        DBMS_OUTPUT.PUT_LINE('HighRank');
    END IF;
END;

【讨论】:

以上是关于如何转换逗号分隔的 varchar 以用于 pl/sql 中的“IN”子句?的主要内容,如果未能解决你的问题,请参考以下文章

在 2 个表之间使用内连接,对于 1 个特定列的多条记录,对整数列求和,使 varchar 列以逗号分隔

将单个逗号分隔的行转换为多行

如何检查存储在varchar列中的逗号分隔列表中是否包含数字?

如何在选择语句的“NOT IN”子句中使用逗号分隔的字符串列表作为 pl/sql 存储的函数参数

将逗号分隔的字符串转换为列表

PL/SQL 动态插入