How to make a join with the stored procedure result? - sql

I want to make a join between a query and the result of stored procedure (for some reason).
my query is:
SELECT COUNT(a.values_key) AS docscount,b.main_code,b.year
FROM SP_name_should_be_here a
INNER JOIN dmr23req b
ON a.values_key = b.req_year || ',' || b.req_ser
AND a.newstateserial = 17
AND a.taskcode = 35
GROUP BY b.main_code,b.year
My stored procedure dmr_get_full_in takes two param

The answer is that you should use an 'iterator function' in the FROM clause:
FROM TABLE(FUNCTION stored_procedure(arg1, arg2)) AS alias(col1, col2, ....)
The 'alias' is not always necessary, but look hard at the column names in the output of executing the procedure directly:
EXECUTE stored_procedure(arg1, arg2)
If that contains unique column names, you'll be OK; if not, you won't and you'll need the AS alias(col1, col2, ...) notation.
Here's an analogue (more or less) to your query.
Trivial function that could be written differently, but works:
CREATE FUNCTION SimpleElements(lo INTEGER, hi INTEGER) RETURNING INTEGER AS Atomic_Number;
DEFINE an INTEGER;
FOREACH SELECT Atomic_Number
INTO an
FROM Elements
WHERE Atomic_Number BETWEEN lo AND hi
ORDER BY Atomic_Number
RETURN an WITH RESUME;
END FOREACH;
END FUNCTION;
Query using TABLE(FUNCTION stored_procedure(arg1, arg2)):
The MOD function is used as simple way of generating some groups to count, but it illustrates the notation which is the main point of the exercise.
SELECT COUNT(*) AS group_count, MOD(b.atomic_number, 3) AS mod_num
FROM TABLE(FUNCTION SimpleElements(1, 10)) AS a(Atomic_Number)
JOIN Elements AS b
ON a.atomic_number = b.atomic_number
GROUP BY mod_num
ORDER BY mod_num;
Output:
3 0
4 1
3 2
Table of Elements
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL UNIQUE CONSTRAINT c1_elements
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
name CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
atomic_weight DECIMAL(8,4) NOT NULL,
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
INSERT INTO elements VALUES( 1, 'H', 'Hydrogen', 1.0079, 'Y');
INSERT INTO elements VALUES( 2, 'He', 'Helium', 4.0026, 'Y');
INSERT INTO elements VALUES( 3, 'Li', 'Lithium', 6.9410, 'Y');
INSERT INTO elements VALUES( 4, 'Be', 'Beryllium', 9.0122, 'Y');
INSERT INTO elements VALUES( 5, 'B', 'Boron', 10.8110, 'Y');
INSERT INTO elements VALUES( 6, 'C', 'Carbon', 12.0110, 'Y');
INSERT INTO elements VALUES( 7, 'N', 'Nitrogen', 14.0070, 'Y');
INSERT INTO elements VALUES( 8, 'O', 'Oxygen', 15.9990, 'Y');
INSERT INTO elements VALUES( 9, 'F', 'Fluorine', 18.9980, 'Y');
INSERT INTO elements VALUES( 10, 'Ne', 'Neon', 20.1800, 'Y');
INSERT INTO elements VALUES( 11, 'Na', 'Sodium', 22.9900, 'Y');
INSERT INTO elements VALUES( 12, 'Mg', 'Magnesium', 24.3050, 'Y');
INSERT INTO elements VALUES( 13, 'Al', 'Aluminium', 26.9820, 'Y');
INSERT INTO elements VALUES( 14, 'Si', 'Silicon', 28.0860, 'Y');
INSERT INTO elements VALUES( 15, 'P', 'Phosphorus', 30.9740, 'Y');
INSERT INTO elements VALUES( 16, 'S', 'Sulphur', 32.0650, 'Y');
INSERT INTO elements VALUES( 17, 'Cl', 'Chlorine', 35.4530, 'Y');
INSERT INTO elements VALUES( 18, 'Ar', 'Argon', 39.9480, 'Y');
…

Related

To find passengers travelling more than thrice on the same route in PL/SQL

Here I am creating three tables, one for storing the Train Info. Another for holding onto the Passenger info and the other one to hold the ticket Info.
create table T_Train_Info(
route_no integer primary key,
source varchar2(50),
destination varchar2(50)
)
create table T_Pay_Info(
pax_id integer primary key,
pax_name varchar2(50),
dob date,
gender varchar2(5)
)
create table T_Tkt_Info(
pax_id integer,
route_no integer,
journey_date date,
seat_no varchar2(5),
primary key(pax_id, route_no, journey_date)
)
In the Train_Info table, I am inserting two unique routes with the same source and destination as there can be different routes for the same source and destination. And filling the other tables in the same manner. In the ticket table, I am repeating values because I aim to find the passenger travelling thrice on the same route.
insert into T_Train_Info values(1, 'Chennai', 'Pune');
insert into T_Train_Info values(2, 'Chennai', 'Pune');
insert into T_Train_Info values(3, 'Bangalore', 'Kolkata');
insert into T_Tkt_Info values(100, 1, to_date('11/03/2022', 'DD/MM/YYYY'), 22);
insert into T_Tkt_Info values(100, 1, to_date('14/08/2022', 'DD/MM/YYYY'), 23);
insert into T_Tkt_Info values(100, 1, to_date('29/08/2022', 'DD/MM/YYYY'), 24);
insert into T_Tkt_Info values(102, 3, to_date('22/08/2022', 'DD/MM/YYYY'), 24);
insert into T_Tkt_Info values(100, 1, to_date('27/08/2022', 'DD/MM/YYYY'), 24);
insert into T_Tkt_Info values(100, 2, to_date('28/08/2022', 'DD/MM/YYYY'), 24);
insert into T_Pay_Info values(100, 'A', to_date('11/03/2022', 'DD/MM/YYYY'), 'F');
insert into T_Pay_Info values(101, 'B', to_date('23/09/2023', 'DD/MM/YYYY'), 'M');
insert into T_Pay_Info values(102, 'A', to_date('11/03/2022', 'DD/MM/YYYY'), 'F');
insert into T_Pay_Info values(103, 'D', to_date('23/09/2023', 'DD/MM/YYYY'), 'M');
insert into T_Pay_Info values(104, 'A', to_date('11/03/2022', 'DD/MM/YYYY'), 'F');
insert into T_Pay_Info values(105, 'A', to_date('23/09/2023', 'DD/MM/YYYY'), 'M');
Here's my procedure which keeps returning the error saying 'exact fetch returns more than requested number of rows' at the select statement. What am I doing wrong here?
create or replace procedure pr_pass_route_details(x in T_Train_Info.Source%type, y in T_Train_Info.Destination%type) is
pr_name T_Pay_Info.Pax_Name%type;
begin
for i in (select pax_id from t_tkt_info group by pax_id,route_no having count(*) >=3) loop
select pax_name into pr_name from t_pay_info where pax_id = i.pax_id and T_Train_Info.Source=x and T_Train_Info.Destination=y;
dbms_output.put_line(pr_name);
end loop;
end pr_pass_route_details;
i’m not sure why you’ve written a SP to do this as you can achieve this with a simple query:
SELECT
pax_id,
route_no,
COUNT(journey_date)
FROM T_Tkt_Info
GROUP BY
pax_id,
route_no
HAVING COUNT(journey_date) = 3

Can I improve this query for use in large tables?

How can I improve this query for use in large tables....?
I use a table ('DataValues') to store a collection of values ('Value') for collections ('Visit_id') ie it records certain values for each visit.
I use a table ('MatchItems') to store dynamic match sets 'MatchSet' of values ('Value'), sets can contain any number of values. The table also has a IsNeg field to indicate if the match should require a value to be not present in the visit collection.
This allows me to dynamically match visits that conform to certain criteria such as
Must contain values A, B and C and NOT D OR C and B AND NOT A.
ie (Value = A and Value = B and Value = C and Value /= D)
or (Value = C and Value = B and Value /= A)
I have a query that delivers a reasonable solution fiddle:
CREATE TABLE DataValues (
id NUMBER(5) CONSTRAINT DataValues_pk PRIMARY KEY,
Visit_id Number(5) ,
Value varchar(5)
);
INSERT INTO DataValues VALUES (1, 1, 'M');
INSERT INTO DataValues VALUES (2, 1, 'I');
INSERT INTO DataValues VALUES (3, 1, 'C');
INSERT INTO DataValues VALUES (4, 1, 'K');
INSERT INTO DataValues VALUES (5, 1, 'E');
INSERT INTO DataValues VALUES (6, 1, 'Y');
INSERT INTO DataValues VALUES (7, 2, 'M');
INSERT INTO DataValues VALUES (8, 2, 'O');
INSERT INTO DataValues VALUES (9, 2, 'U');
INSERT INTO DataValues VALUES (10, 2, 'S');
INSERT INTO DataValues VALUES (11, 2, 'E');
INSERT INTO DataValues VALUES (12, 3, 'C');
INSERT INTO DataValues VALUES (13, 3, 'A');
INSERT INTO DataValues VALUES (14, 3, 'T');
INSERT INTO DataValues VALUES (15, 4, 'S');
INSERT INTO DataValues VALUES (16, 4, 'A');
INSERT INTO DataValues VALUES (17, 4, 'T');
INSERT INTO DataValues VALUES (18, 5, 'M');
INSERT INTO DataValues VALUES (19, 5, 'A');
INSERT INTO DataValues VALUES (20, 5, 'T');
CREATE TABLE MatchItems (
id NUMBER(5) CONSTRAINT MatchItems_pk PRIMARY KEY,
MatchSet Number(5),
Value VARCHAR(5),
IsNeg NUMBER(1) NOT NULL CHECK (IsNeg in (0,1))
);
INSERT INTO MatchItems VALUES (1, 1, 'M', 0);
INSERT INTO MatchItems VALUES (2, 1, 'I', 0);
INSERT INTO MatchItems VALUES (3, 1, 'C', 0);
INSERT INTO MatchItems VALUES (4, 1, 'K', 0);
INSERT INTO MatchItems VALUES (5, 1, 'E', 0);
INSERT INTO MatchItems VALUES (6, 1, 'Y', 0);
INSERT INTO MatchItems VALUES (7, 2, 'C', 0);
INSERT INTO MatchItems VALUES (8, 2, 'A', 0);
INSERT INTO MatchItems VALUES (9, 3, 'A', 0);
INSERT INTO MatchItems VALUES (10, 3, 'T', 0);
INSERT INTO MatchItems VALUES (11, 4, 'S', 1);
INSERT INTO MatchItems VALUES (12, 4, 'A', 0);
INSERT INTO MatchItems VALUES (13, 4, 'K', 1);
INSERT INTO MatchItems VALUES (14, 5, 'A', 0);
INSERT INTO MatchItems VALUES (15, 5, 'T', 0);
SELECT
MatchItems.MatchSet,
DataValues.Visit_id,
GpMatchItems.Count TgtCount,
Count(MatchItems.Id),
sum(MatchItems.IsNeg)
FROM DataValues
LEFT JOIN MatchItems ON MatchItems.Value = DataValues.Value
--AND MatchItems.MatchSet = 4
LEFT JOIN (SELECT
MatchItems.MatchSet,
count(*) Count
FROM MatchItems
WHERE
MatchItems.IsNeg = 0
GROUP BY
MatchItems.MatchSet) GpMatchItems ON GpMatchItems.MatchSet = MatchItems.MatchSet
HAVING
Count(MatchItems.Id) = GpMatchItems.Count
AND sum(MatchItems.IsNeg) = 0
GROUP BY
MatchItems.MatchSet,
DataValues.Visit_id,
GpMatchItems.Count
How can I improve the performance of this query where the DataValues table contains 100m records, and MatchItems may include a collection of 50 sets each of 2 - 20 values?
You can try this version using Analytic functions and see if it performs any better. This query removes the subquery GpMatchItems that you are joining with.
SELECT DISTINCT matchset,
visit_id,
tgtcount,
match_visit_count,
isneg_sum
FROM (SELECT MatchItems.MatchSet,
DataValues.Visit_id,
COUNT (DISTINCT CASE MatchItems.IsNeg WHEN 0 THEN MatchItems.id ELSE NULL END)
OVER (PARTITION BY MatchItems.MatchSet)
AS tgtcount,
COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS match_visit_count,
SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS isneg_sum
FROM DataValues LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
WHERE tgtcount = match_visit_count AND isneg_sum = 0;
I have adjusted EJ's suggestion to include a LEFT JOIN to collect the tgtCount to identify the total number of good matches required in each MatchSet:
SELECT DISTINCT matchset,
visit_id,
tgtcount,
match_visit_count,
isneg_sum
GpMatchItems.count tgtCount
FROM
COUNT (*) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS match_visit_count,
SUM (MatchItems.IsNeg) OVER (PARTITION BY MatchItems.MatchSet, DataValues.Visit_id)
AS isneg_sum
FROM DataValues
LEFT JOIN MatchItems ON MatchItems.VALUE = DataValues.VALUE)
LEFT JOIN ( SELECT
MatchItems.MatchSet,
count(*) Count
FROM MatchItems
WHERE MatchItems.IsNeg = 0
GROUP BY
MatchItems.MatchSet) GpMatchItems
ON GpMatchItems.MatchSet = MatchItems.MatchSet
)
WHERE
tgtcount = match_visit_count
AND isneg_sum = 0;

Selecting from Stored Procedures and Storing SP Results into a Table

I'm trying to build a couple of tables based upon the results of a few Stored procedures inside an Informix Database, that I cannot edit, and the parameter of the second SP requires values from another (will be called a few times). I have figured out what to do, but am having trouble executing it, predominantly because I cannot save my DB into a Temp table so I can then modify it.
If someone could give me some pointers, that would be great.
Some examples of things I've tried
call <stored procedure(...)> INTO TEMP db
and
create temp table name(...)
INSERT INTO namefrom storedprocedure()
and
create temp table name(...)
Select INTO name from storedprocedure()
Kind Regards,
Fox
Here's an example of a user-defined function (aka stored procedure) returning multiple values that are inserted into a temporary table. It uses the stores_demo database.
create function func1()
returning char(15), char(15);
define v_fname, v_lname char(15);
foreach select fname, lname into v_fname, v_lname from customer
return v_fname, v_lname with resume;
end foreach
end function;
create temp table tt1(fname char(15), lname char(15));
insert into tt1 execute function func1();
You can use:
SELECT * FROM TABLE(stored_procedure()) INTO TEMP p32;
This inserts the rows returned by the stored procedure into the temporary table p32.
There may be other ways to do it, but this seemed to work and is fairly straight-forward to understand.
(Tested: Informix 12.10.FC6 on a Mac running macOS 10.14.6 Mojave.)
Test schema
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL PRIMARY KEY
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE,
name CHAR(20) NOT NULL UNIQUE,
atomic_weight DECIMAL(8, 4) NOT NULL,
pt_period SMALLINT NOT NULL
CHECK (pt_period BETWEEN 1 AND 7),
pt_group CHAR(2) NOT NULL
-- 'L' for Lanthanoids, 'A' for Actinoids
CHECK (pt_group IN ('1', '2', 'L', 'A', '3', '4', '5', '6',
'7', '8', '9', '10', '11', '12', '13',
'14', '15', '16', '17', '18')),
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
INSERT INTO elements VALUES( 1, 'H', 'Hydrogen', 1.0079, 1, '1', 'Y');
INSERT INTO elements VALUES( 2, 'He', 'Helium', 4.0026, 1, '18', 'Y');
INSERT INTO elements VALUES( 3, 'Li', 'Lithium', 6.9410, 2, '1', 'Y');
INSERT INTO elements VALUES( 4, 'Be', 'Beryllium', 9.0122, 2, '2', 'Y');
INSERT INTO elements VALUES( 5, 'B', 'Boron', 10.8110, 2, '13', 'Y');
INSERT INTO elements VALUES( 6, 'C', 'Carbon', 12.0110, 2, '14', 'Y');
INSERT INTO elements VALUES( 7, 'N', 'Nitrogen', 14.0070, 2, '15', 'Y');
INSERT INTO elements VALUES( 8, 'O', 'Oxygen', 15.9990, 2, '16', 'Y');
INSERT INTO elements VALUES( 9, 'F', 'Fluorine', 18.9980, 2, '17', 'Y');
INSERT INTO elements VALUES( 10, 'Ne', 'Neon', 20.1800, 2, '18', 'Y');
INSERT INTO elements VALUES( 11, 'Na', 'Sodium', 22.9900, 3, '1', 'Y');
INSERT INTO elements VALUES( 12, 'Mg', 'Magnesium', 24.3050, 3, '2', 'Y');
INSERT INTO elements VALUES( 13, 'Al', 'Aluminium', 26.9820, 3, '13', 'Y');
INSERT INTO elements VALUES( 14, 'Si', 'Silicon', 28.0860, 3, '14', 'Y');
INSERT INTO elements VALUES( 15, 'P', 'Phosphorus', 30.9740, 3, '15', 'Y');
INSERT INTO elements VALUES( 16, 'S', 'Sulphur', 32.0650, 3, '16', 'Y');
INSERT INTO elements VALUES( 17, 'Cl', 'Chlorine', 35.4530, 3, '17', 'Y');
INSERT INTO elements VALUES( 18, 'Ar', 'Argon', 39.9480, 3, '18', 'Y');
The full table has 118 elements listed, of course.
Sample procedure
DROP PROCEDURE IF EXISTS lightweights;
CREATE PROCEDURE lightweights()
RETURNING INTEGER AS atomic_number, VARCHAR(3) AS symbol, VARCHAR(20) AS name;
DEFINE num INTEGER;
DEFINE sym VARCHAR(3);
DEFINE nam VARCHAR(20);
FOREACH SELECT e.atomic_number, e.symbol, e.name
INTO num, sym, nam
FROM elements AS e
WHERE atomic_number < 10
RETURN num, sym, nam WITH RESUME;
END FOREACH;
END PROCEDURE;
Example execution of the procedure to create a temp table
$ sqlcmd -d stores
SQL[3368]: select * from table(lightweights());
1|H |Hydrogen
2|He |Helium
3|Li |Lithium
4|Be |Beryllium
5|B |Boron
6|C |Carbon
7|N |Nitrogen
8|O |Oxygen
9|F |Fluorine
SQL[3368]: select * from table(lightweights()) into temp p32;;
SQL[3369]: select * from p32;
1|H |Hydrogen
2|He |Helium
3|Li |Lithium
4|Be |Beryllium
5|B |Boron
6|C |Carbon
7|N |Nitrogen
8|O |Oxygen
9|F |Fluorine
SQL[3370]: q;
$
Note that in sufficiently recent versions of Informix, you can replace TEMP with STANDARD or RAW to create a permanent table instead of a temporary table (and deleting TEMP is equivalent to replacing it with STANDARD). See SELECT statement > INTO table clauses.

SQL merge statement with multiple conditions

I have a requirement with some business rules to implement on SQL (within a PL/SQL block): I need to evaluate such rules and according to the result perform the corresponding update, delete or insert into a target table.
My database model contains a "staging" and a "real" table. The real table stores records inserted in the past and the staging one contains "fresh" data coming from somewhere that needs to be merged into the real one.
Basically these are my business rules:
Delta between staging MINUS real --> Insert rows into the real
Delta between real MINUS staging--> Delete rows from the real
Rows which PK is the same but any other fields different: Update.
(Those "MINUS" will compare ALL the fields to get equality and distinguise the 3rd case)
I haven't figured out the way to accomplish such tasks without overlapping between rules by using a merge statement: Any suggestion for the merge structure? Is it possible to do it all together within the same merge?
Thank you!
If I understand you task correctly following code should do the job:
--drop table real;
--drop table stag;
create table real (
id NUMBER,
col1 NUMBER,
col2 VARCHAR(10)
);
create table stag (
id NUMBER,
col1 NUMBER,
col2 VARCHAR(10)
);
insert into real values (1, 1, 'a');
insert into real values (2, 2, 'b');
insert into real values (3, 3, 'c');
insert into real values (4, 4, 'd');
insert into real values (5, 5, 'e');
insert into real values (6, 6, 'f');
insert into real values (7, 6, 'g'); -- PK the same but at least one column different
insert into real values (8, 7, 'h'); -- PK the same but at least one column different
insert into real values (9, 9, 'i');
insert into real values (10, 10, 'j'); -- in real but not in stag
insert into stag values (1, 1, 'a');
insert into stag values (2, 2, 'b');
insert into stag values (3, 3, 'c');
insert into stag values (4, 4, 'd');
insert into stag values (5, 5, 'e');
insert into stag values (6, 6, 'f');
insert into stag values (7, 7, 'g'); -- PK the same but at least one column different
insert into stag values (8, 8, 'g'); -- PK the same but at least one column different
insert into stag values (9, 9, 'i');
insert into stag values (11, 11, 'k'); -- in stag but not in real
merge into real
using (WITH w_to_change AS (
select *
from (select stag.*, 'I' as action from stag
minus
select real.*, 'I' as action from real
)
union (select real.*, 'D' as action from real
minus
select stag.*, 'D' as action from stag
)
)
, w_group AS (
select id, max(action) as max_action
from w_to_change
group by id
)
select w_to_change.*
from w_to_change
join w_group
on w_to_change.id = w_group.id
and w_to_change.action = w_group.max_action
) tmp
on (real.id = tmp.id)
when matched then
update set real.col1 = tmp.col1, real.col2 = tmp.col2
delete where tmp.action = 'D'
when not matched then
insert (id, col1, col2) values (tmp.id, tmp.col1, tmp.col2);

How to select from table where the table name is a local variable(informix)

I want to select from table where the table name is a local variable and the column name is another local variable but i get the following error :
The specified table ll_tb_nameis not in the database
CREATE PROCEDURE rmg_request_file ( al_task_code integer)
RETURNING integer as byte;
DEFINE ll_task_code integer;
DEFINE ll_pdf_column varchar(50);
DEFINE ll_tb_name varchar(60);
DEFINE ll_request_file REFERENCES BYTE;
SELECT pdf_column,table_name INTO ll_pdf_column ,ll_tb_name FROM rnmtask WHERE task_code = al_task_code;
FOREACH
SELECT ll_pdf_column into ll_request_file FROM ll_tb_name
return ll_request_file with resume ;
end foreach;
end procedure
Assuming you have a recent enough version of Informix (11.70), you should be able to use Dynamic SQL in SPL like this:
BEGIN;
CREATE TABLE rnmtask
(
pdf_column VARCHAR(32) NOT NULL,
table_name VARCHAR(32) NOT NULL,
task_code INTEGER NOT NULL PRIMARY KEY
);
INSERT INTO rnmtask VALUES("symbol", "elements", 1);
INSERT INTO rnmtask VALUES("name", "elements", 2);
INSERT INTO rnmtask VALUES("atomic_number", "elements", 3);
CREATE PROCEDURE rmg_request_file(al_task_code INTEGER)
RETURNING VARCHAR(255) AS colval;
DEFINE ll_pdf_column VARCHAR(50);
DEFINE ll_tb_name VARCHAR(60);
DEFINE stmt VARCHAR(255);
DEFINE result VARCHAR(255);
SELECT pdf_column, table_name
INTO ll_pdf_column, ll_tb_name
FROM rnmtask
WHERE task_code = al_task_code;
LET stmt = "SELECT " || ll_pdf_column || " FROM " || ll_tb_name;
PREPARE p FROM stmt;
DECLARE C CURSOR FOR p;
OPEN C;
WHILE sqlcode = 0
FETCH C INTO result;
IF sqlcode != 0 THEN
EXIT WHILE;
END IF;
RETURN result WITH RESUME;
END WHILE;
CLOSE C;
FREE C;
FREE p;
END PROCEDURE;
EXECUTE PROCEDURE rmg_request_file(1);
EXECUTE PROCEDURE rmg_request_file(2);
EXECUTE PROCEDURE rmg_request_file(3);
ROLLBACK;
This assumes you have a convenient Table of Elements in your database:
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL PRIMARY KEY CONSTRAINT c1_elements
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE CONSTRAINT c2_elements,
name CHAR(20) NOT NULL UNIQUE CONSTRAINT c3_elements,
atomic_weight DECIMAL(8, 4) NOT NULL,
period SMALLINT NOT NULL
CHECK (period BETWEEN 1 AND 7),
group CHAR(2) NOT NULL
-- 'L' for Lanthanoids, 'A' for Actinoids
CHECK (group IN ('1', '2', 'L', 'A', '3', '4', '5', '6',
'7', '8', '9', '10', '11', '12', '13',
'14', '15', '16', '17', '18')),
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
INSERT INTO elements VALUES( 1, 'H', 'Hydrogen', 1.0079, 1, '1', 'Y');
INSERT INTO elements VALUES( 2, 'He', 'Helium', 4.0026, 1, '18', 'Y');
INSERT INTO elements VALUES( 3, 'Li', 'Lithium', 6.9410, 2, '1', 'Y');
INSERT INTO elements VALUES( 4, 'Be', 'Beryllium', 9.0122, 2, '2', 'Y');
INSERT INTO elements VALUES( 5, 'B', 'Boron', 10.8110, 2, '13', 'Y');
INSERT INTO elements VALUES( 6, 'C', 'Carbon', 12.0110, 2, '14', 'Y');
INSERT INTO elements VALUES( 7, 'N', 'Nitrogen', 14.0070, 2, '15', 'Y');
INSERT INTO elements VALUES( 8, 'O', 'Oxygen', 15.9990, 2, '16', 'Y');
INSERT INTO elements VALUES( 9, 'F', 'Fluorine', 18.9980, 2, '17', 'Y');
INSERT INTO elements VALUES( 10, 'Ne', 'Neon', 20.1800, 2, '18', 'Y');
INSERT INTO elements VALUES( 11, 'Na', 'Sodium', 22.9900, 3, '1', 'Y');
INSERT INTO elements VALUES( 12, 'Mg', 'Magnesium', 24.3050, 3, '2', 'Y');
INSERT INTO elements VALUES( 13, 'Al', 'Aluminium', 26.9820, 3, '13', 'Y');
INSERT INTO elements VALUES( 14, 'Si', 'Silicon', 28.0860, 3, '14', 'Y');
INSERT INTO elements VALUES( 15, 'P', 'Phosphorus', 30.9740, 3, '15', 'Y');
INSERT INTO elements VALUES( 16, 'S', 'Sulphur', 32.0650, 3, '16', 'Y');
INSERT INTO elements VALUES( 17, 'Cl', 'Chlorine', 35.4530, 3, '17', 'Y');
INSERT INTO elements VALUES( 18, 'Ar', 'Argon', 39.9480, 3, '18', 'Y');
I think you should prefix every occurrence of ll_tb_name and ll_pdf_column with the # symbol, even in your SELECT INTO
Use NDS (native dynamic SQL):
EXECUTE IMMEDIATE "SELECT ll_pdf_column into ll_request_file FROM :#ll_tb_name"
USING #ll_tb_name;