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

Rav*_*dra 1 sql oracle select stored-procedures sqlanywhere

以下存储过程是基于搜索类型(id,数字,名称)和搜索文本('samsung galaxy'或任何其他等等)进行产品搜索.让我们假设

search_type是name, 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;
Run Code Online (Sandbox Code Playgroud)

但是我在条件情况下得到以下错误:

[Error] ORA-00905 (18: 49): PL/SQL: ORA-00905: missing keyword
Run Code Online (Sandbox Code Playgroud)

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

ppe*_*rka 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 ))
Run Code Online (Sandbox Code Playgroud)

我在这里做了什么:我用你的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;
Run Code Online (Sandbox Code Playgroud)

但我认为您应该使用该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;
Run Code Online (Sandbox Code Playgroud)

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