0

I regularly have to do support at work using various database tables, checking and comparing values between different tables but always from a starting point of a set of ID values, as strings.

I've set up and saved a SQL Worksheet that I use with all of the various queries I run to do this support, but it takes a lot of copy/pasting of these ID values (in different orders) into all of the different queries. So I'm trying to automate and optimize my time a little.

What I'm hoping to achieve is, at the top of this worksheet, to paste in my ID values as a comma-separated list, store it into a variable somehow, and then run individual queries on the same worksheet and have them use the current value of that variable in their WHERE clauses.

For example,

select 'A1234', 'B5678' into ids from dual; select id, status from tableA where id in ids; select id_2, status_2 from tableB where id in ids; 

Since I'm not running this as a script from top to bottom, I don't think this method would directly work but is there something similar or can I be pointed in the right direction?

As a bonus if possible, I'm also hoping to not need to add the quotation marks (') myself, and rather somehow just use, for example, A1234,B5678 and have it do the work for me but this isn't necessary, just saves me a little bit of time.

4 Answers 4

2

I'd use a temporary table to hold those ids:

-- Run once only: create global temporary table ids (id varchar2(9)); 

Then after having inserted your IDs of interest at the start of the session (see below) or from another table with criteria (e.g. insert into ids select id from tableA where created >= …),
you just have to join to this table to filter on the ids:

-- By joining: select tableA.id, tableA.status from ids join tableA on tableA.id = ids.id; -- By subquerying: select id_2, status_2 from tableB where id_2 in (select id from ids); 

(you can also truncate the table during a session to restart with new ids)

"Simply" inputting your IDs

To input your ids at the start of your session, you can split a string:

insert into ids with i as (select 'A1234,B5678,Z9012' ids from dual), -- ← Here are your IDs serialized with commas. ri(id, ids, nextpos) as ( select '' id, ids, coalesce(nullif(instr(ids, ','), 0), length(ids)) nextpos from i union all select substr(ids, 1, nextpos - 1) id, substr(ids, nextpos + 1), coalesce(nullif(instr(ids, ','), 0), length(ids)) from ri where length(ids) > 0 ) select id from ri where id is not null; 

Well, the expression is not so simple, but that's your worksheet's job to remember it. You'll just have to change the comma-separated string at the start of it.

The whole worksheet (+ initialization) is shown at this fiddle.

Sign up to request clarification or add additional context in comments.

Comments

2

If you are using a client that supports substitution variables, such as SQL*Plus, SQL Developer, SQLcl or others, then you can DEFINE a substitution variable and reuse it throughout the script:

DEFINE ids = "'A1234', 'B5678'" select id, status from tableA where id in (&&ids); select id_2, status_2 from tableB where id in (&&ids); 

You could also write the script to input the value of the subscription variable:

ACCEPT ids PROMPT 'Enter the IDs (each surrounded by single quotes and comma separated, such as ''A1234'', ''B5678''):' select id, status from tableA where id in (&&ids); select id_2, status_2 from tableB where id in (&&ids); 

or, if you do not want to use quotes:

ACCEPT ids PROMPT 'Enter the IDs (such as A1234,B5678):' select id, status from tableA where ',&&ids,' LIKE '%,' || id || ',%'; select id_2, status_2 from tableB where ',&&ids,' LIKE '%,' || id || ',%'; 

Comments

1

One of the option is to recreate a view whenever you have to check and compare different set of ids. At the start of your SQL Sheet (re)Create a viev with fresh list of ids string:

Create Or Replace View v_yours_ids_string AS Select REPLACE(',' || 'A1234, B5678' || ',', ' ', '') as ids_string -- insert your string here From Dual; 

As a bonus if possible, I'm also hoping to not need to add the quotation marks (') myself, and rather somehow just use, for example, A1234,B5678 and have it do the work for me but this isn't necessary, just saves me a little bit of time.

... for such a scenario I put a Replace() function to get ridd of possible spaces within the string and added a comma separator before and after the string to be sure that the matches are accurate cause, here, INSTR() function will be used in Where clauses.
... therefor you will have to change your Where clauses to be like below:

Select id, status From tbl_a Where INSTR((Select ids_string From v_yours_ids_string), ',' || id || ',') > 0; 
ID STATUS
A1234 Status for A1234
B5678 Status for B5678
Select id_2, status_2 From tbl_b Where INSTR((Select ids_string From v_yours_ids_string), ',' || id_2 || ',') > 0; 
ID_2 STATUS_2
A1234 Status_2 for A1234
B5678 Status_2 for B5678

fiddle

NOTE:
The change of Where clauses may be a bit of extra work but once you are done with that you will just have to replace your string with ids in the first command of your script (Create View).

Comments

0

You can save ID's list into PL/SQL variable
or get as STRING or JSON to front and pass to next queries as parameter.

Small example with sample data

create table cat(id int, category varchar2(20),ItemName varchar2(20)); insert into cat values (101,'Fruit','Apple') ,(102,'Fruit','Currant') ,(201,'Vegetable','Cucumber') ,(103,'Fruit','Cherry') ,(202,'Vegetable','Carrot'); create table price(id int, ItemId int, price float); insert into price values (1,101,2.3) ,(2,102,3.1) ,(3,103,3.1) ,(4,201,3.1) ,(5,202,3.1) ; 
DECLARE glIDS varchar2(1000); Items varchar2(1000); BEGIN select listagg(id,',') INTO glIDS from cat where category='Fruit'; select listagg(ItemId,',') into Items from price where ItemId in(select to_number(column_value) as id from xmltable(glIds)) ; DBMS_OUTPUT.PUT_LINE('Items:' || Items); END; / 
status 1 rows affected dbms_output: Items:101,102,103 

Get ids from query output

select listagg(id,',') ids from cat where category='Fruit' 
IDS
101,102,103

and pass them to next query as string (comma-delimited id's)

select * from price where ItemId in(select to_number(column_value) as id from xmltable(?) - there parameter as string '101,102,103' ; 
ID ITEMID PRICE
1 101 2.3
2 102 3.1
3 103 3.1

fiddle

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.