Execute SQL Statement stored in table column - sql

I have insert statement in DB2 database table column and i want to execute that in store procedure
Table:
TB_SQL
(
DATA_SQL VARCHAR(12000)
)
DATA_SQL column contains INSERT statements. for example :
SELECT * FROM TB_SQL
INSERT INTO ADDRESS (COL1, COL2)
SELECT COL1, COL2 FROM DEMO WHERE TYPE='ADDRESS'
How to PREPARE and EXECUTE the INSERT STATEMENT from DATA_SQL Column in DB2 Store Procedure ?
Code I tried:
SET v_SQL=
'SET ?=(
SELECT
DATA_SQL
FROM TB_SQL
WHERE TBNAME='''||v_TBNAME||'''
)
';
PREPARE SQL_QUERY FROM v_SQL;
EXECUTE SQL_QUERY ;
In reality the above PREPARE AND EXECUTE will only prepare SELECT statement and execute SELECT statement.
What i want is, I want to execute the statement that comes as output from SELECT statement.
I also have below option to store the INSERT statement again in another variable
SET v_SQL=
'SET ?=(
SELECT
DATA_SQL
FROM TB_SQL
WHERE TBNAME='''||v_TBNAME||'''
)
';
PREPARE SQL_QUERY FROM v_SQL;
EXECUTE SQL_QUERY INTO v_INSERT_STATEMENT;
PREPARE SQL_INSERT FROM v_INSERT_STATEMENT;
EXECUTE SQL_INSERT;
I believe now i have insert statement stored in v_INSERT_STATEMENT
And again prepared SQL from variable and then executed. But this is not working.

you don't need two dynamic statements...one static and one dynamic makes much more sense.
select data_sql into v_Insert_statement
from tb_sql
where tbname = v_TBNAME;
PREPARE SQL_INSERT FROM v_INSERT_STATEMENT;
EXECUTE SQL_INSERT;

SET v_SQL=
'SET ?=(
SELECT
DATA_SQL
FROM TB_SQL
WHERE TBNAME='''||v_TBNAME||'''
)
';
PREPARE SQL_QUERY FROM v_SQL;
EXECUTE SQL_QUERY INTO v_INSERT_STATEMENT;
PREPARE SQL_INSERT FROM v_INSERT_STATEMENT;
EXECUTE SQL_INSERT;

Related

Create a query as a procedure in BigQuery

I am basically trying to do this MySQL script in BigQuery:
CREATE PROCEDURE `test` (IN tab_name CHAR(40) )
BEGIN
SET #query =
CONCAT(
'SELECT *
FROM ', tab_name );
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
In theory, this should let me run this script:
CALL test(`my_dataset.my_table`)
and it will perform my "SELECT * FROM" script on that table.
So far, this isn't working for me because BQ doesn't want to accept the quotation marks breaking across lines, so it says there is an "Unclosed string literal".
Any idea how I can accomplish this in BQ?
Here is my attempt:
CREATE OR REPLACE PROCEDURE `mydataset.test`(tableName STRING)
BEGIN
DECLARE queryString STRING;
SET queryString = " SELECT * FROM mydataset."||tableName||"";
EXECUTE IMMEDIATE queryString;
-- SELECT queryString;
END;
Execute the procedure:
CALL `mydataset.test`('mytable');

Update query running slow in stored procedure

I have created a query to update the records in database based on certain condition. My query is something like below:
update table1
set value ='some value'
where id in ( /*inner query based on joins*/)
When I execute this query directly in dbeaver tool, it completes in about 20 sec.
There are about 11million records in the database.
But when I run the same query in stored procedure, it takes about 40 minutes.
Below is how my stored procedure is created:
CREATE OR REPLACE PROCEDURE update_query_procedure(input_value varchar)
LANGUAGE 'plpgsql'
AS $$
DECLARE
update_query varchar := ' update table1 '
' set "value" = ''some value'''
' where id in ('
' /* inner query */
' )';
BEGIN
update_query = replace(update_query, 'replace', input_value);
EXECUTE update_query;
END;
$$;
Why is there a difference in execution time when the query is executed directly and from the stored procedure? How can I debug where the issue is?

Missing values error in Oracle dynamic SQL. For the below query its throwing missing values keyword

create or replace procedure temp_test_tb(A varchar2 ) is
lsql varchar(4000);
new_table_name varchar2(100);
fz_date timestamp(50);
begin
select timestamp(max(completion_dt)) into freeze_date from status where run_status=1;
new_table_name := 'common_' ||A|| '_' ||to_char(add_months(fz_date, -1), 'MON');
lsql:='insert into os_temp_tab_2'||
'select * from'||new_table_name||' WHERE ROWNUM<10';
execute immediate lsql;
commit;
end;
This query is throwing an error
Missing values keyword
in Oracle. My inserting table has same columns as the insertion table.
missing space after from
' select * from '||new_table_name|| ' WHERE ROWNUM<10 ';

Can't create a table and select from it while in a plsql procedure in oracle

create or replace procedure sp_test as
begin
CREATE TABLE T AS SELECT col1,col2 FROM t1;
FOR N IN (SELECT * FROM T) LOOP
UPDATE t1 SET t1.col1='value' where col2='value2';
END LOOP;
drop table T;
end;
/
I need to select data into t table from a t1 table in order to apply some modifications, and merge those modifications in t1 table (origin table) before deleting table t.
I m getting this error : PLS-00103
You need to use execute immediate for any ddl inside any pl/sql block. Try the below code:
create or replace procedure sp_test
is
begin
Execute Immediate 'CREATE TABLE T AS SELECT col1,col2 FROM t1';
FOR N IN (SELECT * FROM T) LOOP
Execute immediate 'UPDATE t1 SET t1.col1=''value'' where col2=''value2''';
END LOOP;
execute immediate 'drop table T';
end;
/
Thanks everybody for your contribution, I tried something that works :
A cursor for update.
Thanks for help :)

DB2 dynamic table name

I want to count the rows of a number of tables. But the table name should be used dynamically. I want to do that within one SQL statement.
I tried it with
BEGIN ATOMIC
FOR tmp AS (
SELECT tabschema || '.' || tabname tbl
FROM syscat.tables WHERE tabname LIKE '%CD') DO
(SELECT COUNT(*) FROM tmp.tbl);
END FOR;
END
but I receive the error
DB21034E The command was processed as an SQL statement because it was not a
valid Command Line Processor command. During SQL processing it returned:
SQL0204N "TMP.TBL" is an undefined name. LINE NUMBER=1. SQLSTATE=42704
and found no other working solution...
Is there a solution for that?
Thanks in advance.
I assume that your SELECT COUNT(*) FROM tmp.tbl should translate in multiple statements like
select count(*) from TABLECD
select count(*) from TABLE2CD
...
However, your query will try to do a count of the table TBL in the schema TMP.
You'll have to prepare the complete SQL statement, store it in a variable and pass it to the PREPARE statement (documentation ).
A rather complete stored procedure which somewhat fits your requirements can be found here . The result of the counts will be stored in a table COUNTERS which you can query afterwards.
//edit: this is the example from the topic, adapt to work (not tested since I have no DB2 instance to test atm):
CREATE PROCEDURE tableCount()
LANGUAGE SQL
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5);
DECLARE vTableName VARCHAR(20);
DECLARE vTableCount INTEGER;
DECLARE stmt varchar(2000);
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE c1 CURSOR FOR
SELECT tabname from syscat.tables where tabschema='DB2ADMIN';
DECLARE C2 CURSOR FOR S2
DECLARE CONTINUE HANDLER FOR not_found
SET stmt = '';
Delete from COUNTERS;
OPEN c1;
getRows:
LOOP
FETCH c1 INTO vTableName;
IF SQLCODE = 0 THEN
SET stmt ='SELECT Count(*) FROM ' || vTableName;
PREPARE S2 FROM stmt;
OPEN C2;
SET vTableCount = 0;
FETCH C2 INTO vTableCount;
INSERT INTO COUNTERS (tableName, tableCount)
VALUES (vTableName, vTableCount);
CLOSE C2;
ELSE
LEAVE getRows;
END IF;
END LOOP getRows;
CLOSE c1;
END