使用与插入相同的变量存在的 Oracle 案例

Posted

技术标签:

【中文标题】使用与插入相同的变量存在的 Oracle 案例【英文标题】:Oracle case when exists using same variable as insert into 【发布时间】:2014-11-24 10:29:41 【问题描述】:

我遇到了一段 T-SQL,我正试图将其转换为 Oracle。它看起来像这样:

SET @local variable= 
    CASE 
        when exists (select field from table where value=0) then 0
        when exists (select same field from same table where value=1) then 1
        when exists (select same fieldfrom same table where value=2) then 1
        else @local variable
    END

@local 变量是在过程前面的查询结果中设置的。

现在,我尝试通过以下方式将其转换为 Oracle:

BEGIN
    SELECT CASE
        WHEN EXISTS (
            SELECT field
            FROM table
            WHERE value = 0
        )
        THEN 0
        WHEN EXISTS (
            SELECT same field
            FROM same table
            WHERE value = 1
        )
        THEN 1
        WHEN EXISTS (
            SELECT same field
            FROM same table
            WHERE value = 2
        )
        THEN 1
        ELSE localvariable
    END 
    INTO localvariable
    FROM DUAL;
END;

然而,PL/SQL 似乎不喜欢我在 else 语句中使用 @localvariable 和在 into 语句中。我知道这可能不是一个写得很好的查询,但这里的解决方案是什么?我如何在合法的 PL/SQL 中编写这个?

【问题讨论】:

【参考方案1】:

CASEEXISTS不能以您期望的方式使用。

你可以这样做。

DECLARE
    localvariable1 NUMBER;
    localvariable2 NUMBER;
    localvariable3 NUMBER;
    localvariable  NUMBER;
BEGIN

    SELECT COUNT(DECODE(value,'0',field)) as v1,
           COUNT(DECODE(value,'1',field)) as v2,
           COUNT(DECODE(value,'2',field)) as v3 
    INTO
           localvariable1,
           localvariable2,
           localvariable3
    FROM table;

    IF(localvariable1 > 0)
    THEN
        localvariable := 0;
    ELSIF(localvariable2 > 0 OR localvariable3 > 0 )
    THEN
        localvariable := 1;
    END;
END;

【讨论】:

对表进行全面扫描。【参考方案2】:

我不能假设表中只有一条记录,或者where 子句包含其他过滤以将结果集缩小到一条记录。以下建议重复了如果存在多行且每行的 Value 字段可能不同的行为,则结果将基于找到的最低值。

declare LocalVar number;
...
select case Min( Value )
         when 0 then 0
         when 1 then 1
         when 2 then 1
         else LocalVar end 
into LocalVar
from SomeTable
where Value between 0 and 2
  and possible_other_criteria;

事实上,T-SQL 查询写得很糟糕。当您只能在一个表中获得相同的结果时,为什么还要对同一个表进行三个查询。它也可以更改为与 PL/SQL 几乎相同的查询。其实看起来语法是一样的。

【讨论】:

【参考方案3】:

正确的方法是使用临时变量来分配(在 Oracle 11.2g 上测试):

宣布 tmp pls_integer; 开始 选择案例 当存在时( 选择 1 FROM any_table1 WHERE 值 = 0 ) 那么 0 当存在时( 选择 1 FROM any_table2 WHERE 值 = 1 ) 那么 1 当存在时( 选择 1 来自 any_table3 WHERE 值 = 2 ) 那么 1 ELSE:局部变量 结尾 进入tmp 从双; :局部变量:= tmp; 结尾; /

【讨论】:

以上是关于使用与插入相同的变量存在的 Oracle 案例的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 插入、选择和不存在

在 R 中比较和连接数据框

Oracle查询计算与日期数组完全相同的匹配

Oracle-在不存在的地方插入select max

表 'users' 超出 Oracle 空间配额

oracle中SQL的缓存