Sql 存储过程中的case、when和then on where子句不起作用

Sql 存储过程中的case、when和then on where子句不起作用,sql,oracle,select,stored-procedures,sqlanywhere,Sql,Oracle,Select,Stored Procedures,Sqlanywhere,以下存储过程正在根据搜索类型(id、编号、名称)和搜索文本(“samsung galaxy”或任何其他等等)执行产品搜索。 让我们假设 搜索类型为名称和 搜索文本为“三星galaxy” 基于这个条件,我编写了以下存储过程 create or replace procedure product_search( search_type IN varchar2, search_text IN varchar2, status IN varchar2) is cursor c1

以下存储过程正在根据搜索类型(id、编号、名称)和搜索文本(“samsung galaxy”或任何其他等等)执行产品搜索。 让我们假设

搜索类型为名称搜索文本为“三星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;
但我得到了以下条件下的错误:

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

你能给我建议一下如何解决这个问题吗?即使你能给我建议另一种解决这个问题的方法,那也太好了。谢谢

这不是在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 ))
我在这里所做的是:我制定了一个常规的逻辑表达式,你用这个结构制定的。在
WHERE
子句中,CASE-WHEN-THEN不能按您所做的方式使用-它返回某种值,而您对此没有做任何处理,这就是为什么会出现“missing keyword”错误

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

但我认为您应该使用构造,并将单个查询分为三个查询:

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;

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

这不是在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 ))
我在这里所做的是:我制定了一个常规的逻辑表达式,你用这个结构制定的。在
WHERE
子句中,CASE-WHEN-THEN不能按您所做的方式使用-它返回某种值,而您对此没有做任何处理,这就是为什么会出现“missing keyword”错误

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

但我认为您应该使用构造,并将单个查询分为三个查询:

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;

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

您的上一句话仅部分正确。如果在一个存储过程中使用If-then-else语句将三个单独的查询分开,那么在查询计划中只会存储三个路径中的一个(第一个要执行的路径)。在重新编译之前,其他2个查询将在此非最佳查询计划下执行。您的上一条语句仅部分正确。如果在一个存储过程中使用If-then-else语句将三个单独的查询分开,那么在查询计划中只会存储三个路径中的一个(第一个要执行的路径)。在重新编译之前,其他2个查询将在此非最佳查询计划下执行。