case,when,然后在存储过程中的where子句不起作用

时间:2013-03-13 09:41:31

标签: sql oracle select stored-procedures sqlanywhere

以下存储过程是根据搜索类型(ID,编号,名称)和搜索文本('samsung galaxy'或任何其他等等)进行产品搜索。 我们假设

search_type是名称 search_text是'samsung galaxy'

根据这些条件,我编写了以下存储过程。

create or replace procedure product_search(
    search_type IN varchar2,
    search_text IN varchar2,
    status IN varchar2)
is
cursor c1 is 
    SELECT p.pm_oid , p.item_name  
        FROM prism_item_hierarchy p
        WHERE 
        CASE search_type
             WHEN 'id' THEN p.pm_oid LIKE '%'||search_text||'%'
             WHEN 'name' THEN  Lower(p.item_name ) LIKE '%'||search_text||'%'
             ELSE p.item_number LIKE '%'||search_text
        END;

BEGIN
    open c1;
    -- fetch c1 into 

    close c1;

 END;

但我在case-when-condition时收到以下错误:

[Error] ORA-00905 (18: 49): PL/SQL: ORA-00905: missing keyword

你能否告诉我如何解决这个问题,即使你提出了另一种方法来解决这个问题,也会很棒。感谢

1 个答案:

答案 0 :(得分:5)

这不是在Oracle中如何完成的。例如,您可以通过以下方式重写查询:

SELECT p.pm_oid , p.item_name  
        FROM prism_item_hierarchy p
        WHERE 
         (search_type='id' AND (p.pm_oid LIKE '%'||search_text||'%')) 
         OR (search_type='name' AND ( Lower(p.item_name ) LIKE '%'||search_text||'%'))
         OR (search_type NOT IN ('id', 'name') AND (p.item_number LIKE '%'||search_text ))

我在这里做了什么:我用CASE-WHEN-THEN结构制定了一个传统的逻辑表达式。在WHERE子句中,CASE-WHEN-THEN不能像你那样使用它 - 它返回某种价值,你没有做任何事情,这就是为什么你得到了“缺少关键字“错误...

考虑到这一点,你可以这样做,相应地定义和使用返回值(当心,但在这种情况下,这是一种扭曲和丑陋的方法!):

SELECT p.pm_oid , p.item_name  
        FROM prism_item_hierarchy p
        WHERE 
        1 = CASE 
                 WHEN search_type='id' AND (p.pm_oid LIKE '%'||search_text||'%') THEN 1
                 WHEN search_type='name' AND (Lower(p.item_name ) LIKE '%'||search_text||'%') THEN 1
                 WHEN search_type NOT IN ('name','id') AND (p.item_number LIKE '%'||search_text) THEN 1
                 ELSE 0
        END;

但我认为你应该使用IF-THEN-ELSIF-ELSE构造,并将单个查询分成三个查询:

IF search_type = 'id' THEN
    SELECT p.pm_oid , p.item_name  
    FROM prism_item_hierarchy p
    WHERE p.pm_oid LIKE '%'||search_text||'%'

ELSIF search_type = 'name' THEN
    SELECT p.pm_oid , p.item_name  
    FROM prism_item_hierarchy p
    WHERE Lower(p.item_name ) LIKE '%'||search_text||'%'

ELSE
    SELECT p.pm_oid , p.item_name  
    FROM prism_item_hierarchy p
    WHERE p.item_number LIKE '%'||search_text

END IF;

这种方法,因为它使用三种不同的查询更为理想:查询优化器将能够为每种查询使用不同的配置文件,因此通常,您最终会在每种配置文件上获得增强的性能。