Reputation: 586
In the initialization section of an oracle package I try to determine the current ID of certain objects with a given name. Reason: The package is used on multiple databases and the IDs of these objects my vary while their names are constant.
The code looks like this:
SELECT id INTO varCat FROM myTable WHERE Type = 'Object' AND Name = 'Cat';
SELECT id INTO varDog FROM myTable WHERE Type = 'Object' AND Name = 'Dog';
...
SELECT id INTO varMouse FROM myTable WHERE Type = 'Object' AND Name = 'Mouse';
Is there a way to optimize the queries and perhaps do it in a single query?
Upvotes: 0
Views: 12499
Reputation: 31648
You could use a loop with the simple select query.
FOR rec IN (SELECT ID, NAME
FROM myTable
WHERE TYPE = 'Object' AND name in ('Cat', 'Dog', 'Mouse'))
LOOP
IF rec.NAME = 'Cat'
THEN
varCat := rec.ID;
ELSIF rec.NAME = 'Dog'
THEN
varDog := rec.ID;
..
..
END IF;
END LOOP;
Upvotes: 1
Reputation: 1
INSERT INTO mytable (varCat, varDog, varMouse) VALUES( (SELECT id FROM Table1 where id), (SELECT tax_status_id FROM tax_status WHERE tax_status_code = ?), (SELECT recipient_id FROM recipient WHERE recipient_code = ?))
Upvotes: -2
Reputation: 5565
Maybe with the pivot query:
select cat, dog, mouse
into varCat, varDog, varMouse
from (select * from mytable where Type = 'Object')
pivot (max(id) for name in ('Cat' cat, 'Dog' dog, 'Mouse' mouse))
This query will return highest ID
for each name
column. If you have more names add them into the list in the last line of a query. Also, you can choose another aggregate function.
Upvotes: 2
Reputation: 191235
You can combine them with a manual pivot:
select max(case when name = 'Cat' then id end),
max(case when name = 'Dog' then id end),
max(case when name = 'Mouse' then id end)
into varCat, varDog, varMouse
from mytable
where type = 'Object'
and name in ('Cat', 'Dog', 'Mouse');
Quick demo:
create table mytable (id number, type varchar2(10), name varchar2(10));
insert into mytable (id, type, name) values (1, 'Object', 'Mouse');
insert into mytable (id, type, name) values (2, 'Object', 'Cat');
insert into mytable (id, type, name) values (3, 'Object', 'Dog');
set serveroutput on
declare
varCat mytable.id%type;
varDog mytable.id%type;
varMouse mytable.id%type;
begin
select max(case when name = 'Cat' then id end),
max(case when name = 'Dog' then id end),
max(case when name = 'Mouse' then id end)
into varCat, varDog, varMouse
from mytable
where type = 'Object'
and name in ('Cat', 'Dog', 'Mouse');
dbms_output.put_line('varCat: ' || varCat);
dbms_output.put_line('varDog: ' || varDog);
dbms_output.put_line('varMouse: ' || varMouse);
end;
/
varCat: 2
varDog: 3
varMouse: 1
PL/SQL procedure successfully completed.
If the combination of type and name is not unique then your current code would error (too-many-rows); this would silent pick the highest ID.
If you're also getting IDs for other types where the name might be the same, you can include the type in the case expression too:
select max(case when type = 'Object' and name = 'Cat' then id end),
max(case when type = 'Object' and name = 'Dog' then id end),
max(case when type = 'Object' and name = 'Mouse' then id end)
-- , ... other combinations you want to get
into varCat, varDog, varMouse --, ... other variables
from mytable
where (type = 'Object' and name in ('Cat', 'Dog', 'Mouse'))
or ... ;
Upvotes: 6