Frage

The following stored procedure is doing a product search based on search type(id, number, name) and search text('samsung galaxy' or any other etc..). Let us assume

search_type is name and search_text is 'samsung galaxy'

based on this conditions I've written the following stored procedure.

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;

But I am getting the following error on the case-when-condition:

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

Could you please suggest to me how to solve this problem, even if you suggest an other way to solve this problem, it would be great. Thanks

War es hilfreich?

Lösung

This is not how it can be done in Oracle. You can for example rewrite your query this way:

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 ))

What I had done here: I formulated a conventional logical expression of what you formulated with the CASE-WHEN-THEN construct. in the WHERE clause, the CASE-WHEN-THEN can't be used the way you did it - it returns some kind of value, and you didn't do anything with that, that is why you got the "missing keyword" error...

With that in mind, you could do it this way, defining and using the return value accordingly (Beware though, this is a twisted and ugly approach in this case!):

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;

But I think that you should use the IF-THEN-ELSIF-ELSE construct, and separate the single query into three queries:

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;

This approach, as it uses three different queries is more optimal: the query optimizer will be able to use different profiles for each, so in general, you'll end up with enhanced performance on each.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top