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