DELIMITER $$
CREATE PROCEDURE insert_priority_rows()
BEGIN
DECLARE max_heuristics INT DEFAULT 10;
DECLARE heuristic_ID INT;
DECLARE cur CURSOR FOR
SELECT heuristicID
FROM heuristics;
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET heuristic_ID = 0;
DECLARE #study_ID INT;
SELECT MAX(studyID) INTO #study_ID FROM study;
OPEN cur;
REPEAT
FETCH cur INTO heuristic_ID;
IF heuristic_ID = 0 THEN
LEAVE;
END IF;
INSERT INTO heuristic_priority (studyID, heuristicID, h_priority)
VALUES (#study_ID, heuristic_ID, 'm');
UNTIL heuristicID = 0 END REPEAT;
CLOSE cur;
END$$
DELIMITER ;
It throws up an error as follows:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use
near '#study_ID INT;
What should I do to rectify this issue?
You don't need most of that code. The loop can be replaced with this query:
DELIMITER $$
CREATE PROCEDURE insert_priority_rows()
BEGIN
INSERT INTO heuristic_priority (studyID, heuristicID, h_priority)
SELECT m.max_study_id, h.heuristicID, 'm'
FROM heuristics AS h
CROSS JOIN (SELECT MAX(studyID) as max_study_id FROM study) AS m;
END$$
Related
I am writing a SQL stored procedure in Snowflake (language SQL NOT Javascript).
I am trying to save a count from a SELECT statement into a variable and the table name for the select statement needs to come from a variable.
Here is what I have so far but this is failing. I don't know where to put the USING or if I can even do this? I feel like I just don't have it syntactically correct yet.
create or replace procedure myprocedure(DBNAME varchar(16777216))
returns int
language sql
as
$$
DECLARE
excludeCount int;
fullyQualifiedProceduresTable varchar(16777216);
BEGIN
fullyQualifiedProceduresTable := CONCAT(DBNAME, '.INFORMATION_SCHEMA.PROCEDURES');
excludeCount := (SELECT count(*) as count from TABLE (?) WHERE PROCEDURE_OWNER = '<ROLE NAME>') USING fullyQualifiedProceduresTable ;
IF (excludeCount > 0) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$;
This is what I got to work using slightly different syntax for using variables.
Syntax taken from here
create or replace procedure myprocedure(DBNAME varchar(16777216))
returns int
language sql
as
$$
DECLARE
excludeCount int;
fullyQualifiedProceduresTable varchar(16777216);
BEGIN
SELECT CONCAT(:DBNAME, '.INFORMATION_SCHEMA.PROCEDURES') into :fullyQualifiedProceduresTable;
SELECT count(*) into :excludeCount from IDENTIFIER(:fullyQualifiedProceduresTable) WHERE PROCEDURE_OWNER = '<role>';
IF (excludeCount > 0) THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
$$;
I am not sure why you need a procedure for this. Could you not do...
set table_name='abc';
set excludeCount=(select case when count(*)>0 then 1 else 0 end from identifier($table_name));
try this
call my_proc('bus_day');
create or replace procedure my_proc(table_name varchar)
returns table(a integer)
language sql
as
$$
declare
res RESULTSET;
query varchar default 'SELECT count(*) FROM ' || :table_name ;
begin
res := (execute immediate :query);
return table (res);
end;
$$;
Here is my stored procedure:
CREATE PROCEDURE PROC1()
LANGUAGE SQL
BEGIN
DECLARE EOF INT DEFAULT 0;
DECLARE SQLCODE INT DEFAULT 0;
DECLARE var_MYID INT;
DECLARE PCURSOR CURSOR FOR SELECT MYID FROM MYTABLE
OPEN PCURSOR;
WHILE EOF = 0 DO
FETCH FROM PCURSOR INTO var_MYID;
IF SQLCODE = 100 THEN
SET EOF = 1;
ELSE
-- nested cursor goes here
END IF;
END WHILE;
CLOSE PCURSOR;
END
SQLCODE = 100 newer happens (it's always 0 when I debug). So it becomes infinite loop. I'm not using
DECLARE CONTINUE HANDLER FOR NOT FOUND SET EOF = 1;
because I'm going to use another nested cursor.
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
I am unable to use %notfound as I get the following error. How can I get past this?? I'm unable to figure out a way to use cursors apart from this method. Please help with other methods to use a cursor loop without using %notfound.
The character "%" following "EXIT WHEN c_rqstid" is not valid.. SQLCODE=-7, SQLSTATE=42601, DRIVER=3.63.123 SQL Code: -7, SQL State: 42601
I have set # as the delimeter and the code is as follows
create PROCEDURE TEST111()
AS:
begin
DECLARE c_id integer;
DECLARE c_isactive integer;
DECLARE c_status integer;
CURSOR c_rqstid is SELECT REQUESTID,REQUESTSTATUS,ISACTIVE FROM SAMPLE.REQUEST;
OPEN c_rqstid;
FOR LOOP FETCH c_rqstid into c_id,c_status,c_isactive ;
----will code this later
EXIT WHEN c_rqstid%NOTFOUND;
END LOOP;
CLOSE c_rqstid;
end
#
Thanks for any help in advance...
You'll need to check the SQLCODE or SQLSTATE variables:
http://pic.dhe.ibm.com/infocenter/db2luw/v10r1/topic/com.ibm.db2.luw.apdv.sqlpl.doc/doc/c0009028.html
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
WHILE(SQLSTATE = '00000') DO
SET p_sum = p_sum + p_sal;
FETCH FROM c INTO p_sal;
END WHILE;
I wanted to know how to insert into a table using stored procedures in DB2 using SQL.
I have created a table as follows:
create table ADCLIBT.Itest
(ITNBR CHAR(15) CCSID 65535 NOT NULL DEFAULT '');
This table contains a list of items. Using this list I want to insert various other fields to another table. But, just for example sake, let's say I just want to insert these values one by one using cursors.
I have written the stored procedure as follows:
create procedure ADCLIBT.itest1()
LANGUAGE SQL
BEGIN
DECLARE itemno char(15);
DECLARE END_TABLE INT DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '20000';
DECLARE c CURSOR FOR
select ITNBR from ADCLIBT.ITEMAT;
DECLARE CONTINUE HANDLER FOR not_found
SET END_TABLE = 1;
open c;
fetch from c into itemno;
WHILE END_TABLE = 0 DO
insert into ADCLIBT.ITEST
(ITNBR)
values
(select a.ITNBR from ADCLIBT.ITEMAT a where ITNBR=itemno GROUP BY a.ITNBR);
END WHILE;
Close c;
END;
This is giving me an infinite loop. Can anyone please tell me how do I stop the infinite loop and insert these records. I want to use the cursor because I want to further use itemno to compare and get single results.
You are opening the cursor but not feching in the while, you must do a fetch in the while of the cursor. Here an example from the IBM documentation.
CREATE PROCEDURE sum_salaries(OUT sum INTEGER) LANGUAGE SQL
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE p_sum INTEGER;
DECLARE p_sal INTEGER;
DECLARE c CURSOR FOR SELECT SALARY FROM EMPLOYEE;
SET p_sum = 0;
OPEN c;
FETCH FROM c INTO p_sal;
WHILE(SQLSTATE = '00000') DO
SET p_sum = p_sum + p_sal;
FETCH FROM c INTO p_sal;
END WHILE;
CLOSE c;
SET sum = p_sum;
END%