DB2 Stored Procedure issue - stored-procedures

I have a requirement to frame a query which will fetch all the tables from database and then have to reset one particular column value to 0 from each table. The problem is tables will be added dynamically in future and there is no fixed number of tables .
I'm pretty new to this DB2 and never wrote a stored procedure but i tried with the below procedure which I'm getting SQL state errors . Could anyone help me out in this issue please .
CREATE PROCEDURE ResetCoulmnValues ()
BEGIN
DECLARE TABLE_NAME Varchar(50) ;
DECLARE COLUMN_NAME Varchar(50) ;
DECLARE TableDetails CURSOR FOR
SELECT TABNAME,COLNAME from SYSCAT.COLUMNS where tabschema = 'CALL' and TABNAME<>'ASC_TOTAL_CALL_CONTINUATION_EVENT';
OPEN TableDetails;
FETCH TableDetails
INTO TABLE_NAME, COLUMN_NAME;
UPDATE TABLE_NAME
SET COLUMN_NAME = 0;
CLOSE TableDetails ;
END;
CALL ResetCoulmnValues ()
Error:
DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601,
SQLERRMC=END-OF-STATEMENT;BLE_NAME Varchar(50);,
DRIVER=3.57.110 SQLState: 42601 ErrorCode: -104
Error occurred in:
CREATE PROCEDURE ResetCoulmnValues ()
BEGIN
DECLARE TABLE_NAME Varchar(50)

Related

Redshift error - [42703][500310] [Amazon](500310) Invalid operation: record "list" has no field "table_name";

[42703][500310] Amazon Invalid operation: record "list" has no field "table_name";
I got the above error while executing stored procedure in redshift. The stored procedure as below
My table structure
admin.table_primary_keys
(
table_name varchar(200),
primary_key varchar(500)
)
Stored procedure -
CREATE OR replace PROCEDURE admin.sp_load_duplicate_data()
language plpgsql
AS
$$
DECLARE
list RECORD;
keys varchar(2000);
Table_name varchar(2000);
query varchar(2000);
BEGIN
FOR list IN
SELECT table_name,primary_key FROM admin.table_primary_keys
LOOP
select list.primary_key into keys;
select list.table_name into Table_name;
query:='select '''||Table_name||''',count(1) from (select '||keys||', count(1) from '||Table_name||' group by '||keys|| ' having count(1) >1)';
--EXECUTE 'insert into audit.duplicate_table_list(table_name,count) ' || query;
EXECUTE query;
END LOOP;
END;
$$;
call admin.sp_load_duplicate_data();
Error - [42703][500310] Amazon Invalid operation: record "list" has no field "table_name";
Any help would be appreciated. thanks
i figured out the answer for this above issue. i just renamed the table columns as tablename,primarykey ( instead of table_name,primary_key). i think error is due to keywords/reserved word,etc
Thanks

Dynamic Stored Procedure in Oracle

Gurus, I have stored procedure to has to executed on a dynamic table. Here is how the stored procedure looks like.
create or replace PROCEDURE EFX_RECON_UPDATE_SPROC(
FILENAME IN VARCHAR2 ,
SOURCE IN VARCHAR2 )
AS
TABLE_NAME VARCHAR2(200);
query_str VARCHAR2(500);
cnt NUMBER(10);
BEGIN
-- Create dynamic table for each fullfilment system.
TABLE_NAME := SOURCE||'_BRM_OMC_RECON_T';
query_str :='SELECT count(*) from ' || SOURCE || '_BRM_OMC_RECON_T where PROCESSINGFILENAME='''||FILENAME||''';';
EXECUTE IMMEDIATE query_str;
query_str:='MERGE INTO '||TABLE_NAME||' T
USING (
SELECT
ERRORCODE, PROCESSINGFILENAME,
RECORDNUMBER from ERROR_UPLOAD_T
) TMP
ON (T.RECORDNUMBER = TMP.RECORDNUMBER and
T.PROCESSINGFILENAME= TMP.PROCESSINGFILENAME and
T.PROCESSINGFILENAME='''||FILENAME||''')
WHEN MATCHED THEN
UPDATE SET
T.STATUS = ''ERROR'',
T.ERRORSOURCE = ''BRM'',
T.ERRORCODE = TMP.ERRORCODE';
EXECUTE IMMEDIATE query_str;
COMMIT;
END EFX_RECON_UPDATE_SPROC;
I get this error while executing the stored procedure. The problem is with FILENAME and I have enclosed it in ' quot.
ORA-00933: SQL command not properly ended
ORA-06512: at "PIN149.EFX_RECON_UPDATE_SPROC", line 12
According to the error message the problem is on this line:
EXECUTE IMMEDIATE query_str;
It should be:
EXECUTE IMMEDIATE query_str INTO cnt;
And the semicolon should be removed from the SELECT string.
Although the variable cnt is not used elsewhere so I'm not sure what that statement is supposed to accomplish.

How can I check if a stored procedure exists in PERVASIVE database before creating it?

I want to create a stored procedure in a Pervasive database, but only if it does not yet exist.
I found something for SQL Server:
IF NOT EXISTS (SELECT *
FROM sys.objects
WHERE type = 'P' AND OBJECT_ID = OBJECT_ID('dbo.MyProc'))
exec('CREATE PROCEDURE [dbo].[MyProc] AS BEGIN SET NOCOUNT ON; END')
GO
I found that code on this link How to check if a stored procedure exists before creating it.
So I want something really similar for Pervasive.
There's no way to execute the IF NOT EXISTS syntax outside of a Stored Procedure in Pervasive. You could create a procedure taking a procedure name and drop it if it exist. Something like:
CREATE PROCEDURE DropProcIfExists(in :procname char(20))
AS
BEGIN
IF( EXISTS (SELECT xp$Name FROM X$proc WHERE Xp$Name = :procname) ) THEN
Exec('DROP Procedure "' + :procname + '"') ;
END IF;
End#
call DropProcIfExists ('myProc')#
So your SQL would be something like:
call DropProcIfExists('MyNewProc')#
Create Procedure MyNewProc()
AS
BEGIN...

Execute Dynamic DDL statement in teradata stored procedure?

How to Execute Dynamic DDL statements IN TERADATA?
CREATE PROCEDURE DROP_INDEXES(IN indexs varchar(1000),IN p_database VARCHAR (8000),IN p_table varchar(8000))
BEGIN
DECLARE L_SQL VARCHAR(400);
SET L_SQL= 'DROP INDEX '||trim(indexs)||' ON '||trim(db_name)|| '.'|| trim(tablename);
EXECUTE IMMEDIATE L_SQL;
END ;
I need to call this child_procedure(DROP_INDEXES) from parent procedure, but during executing of the parent_procedure, after executing this procedure
CALL DROP_INDEXES(indexs,db_name,tablename);
automatically gets exit from the parent_procedure, the next statement is not executing from parent_procedure.
This is the error i'm getting:
Executed as Single statement. Failed [3722 : HY000] SP_DROP_INDEXES:
Only a COMMIT WORK or null statement is legal after a DDL Statement.
Elapsed time = 00:00:00.326
Kindly do help me regarding my issue.
Thanks in advance.
In Teradata each DDL must be committed individually. Your session is running in ANSO mode, thus you need to add ;COMMIT; to the SQL string.
This should work:
SET L_SQL= 'DROP INDEX '||trim(indexs)||' ON '||trim(db_name)|| '.'|| trim(table name) || ';COMMIT;'
Try a different syntax:
REPLACE PROCEDURE DROP_INDEXES(IN indexs varchar(1000), IN p_database VARCHAR (8000),IN p_table varchar(8000))
BEGIN
DECLARE L_SQL VARCHAR(400);
SET L_SQL= 'DROP INDEX '||trim(indexs)||' ON '||trim(p_database)|| '.'|| trim(p_table);
--EXECUTE IMMEDIATE L_SQL;
CALL DBC.SysExecSQL( L_SQL );
END ;
REPLACE PROCEDURE PROC_TEST1 (IN db_name varchar(30),IN tablename varchar(30),IN indexs varchar(30))
BEGIN
CALL DROP_INDEXES(indexs,db_name,tablename);
insert into test2 (charcol) select user;
END;
call proc_test1(DATABASE,'test2','idx_test2');

DB2 Can't REFRESH Materialized Query Table (MQT) in Stored Procedure

I'm having trouble refreshing an MQT inside of a stored procedure.
I'm receiving the following error when attempting to refresh the table :
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "REFRESH" was found following "ANGUAGE SQL BEGIN " . Expected tokens may include: "TRUNCATE" .
/**********
* CREATE A NEW DUMMY TABLE AND INSERT DUMMY DATA
**********/
CREATE TABLE DELETE_ME (
COLUMN_A DECIMAL(5)
);
INSERT INTO DELETE_ME (COLUMN_A) VALUES (1);
INSERT INTO DELETE_ME (COLUMN_A) VALUES (2);
INSERT INTO DELETE_ME (COLUMN_A) VALUES (3);
/**********
* CREATE A MATERIALIZED QUERY USING THE DUMMY TABLE
**********/
CREATE TABLE MQT_TEST AS (
SELECT COLUMN_A
FROM DELETE_ME
)
DATA INITIALLY DEFERRED
REFRESH DEFERRED
ENABLE QUERY OPTIMIZATION
NOT LOGGED INITIALLY;
COMMIT;
/**********
* CREATE A SIMPLE PROCEDURE TO REFRESH THE MATERIALIZED QUERY
**********/
CREATE OR REPLACE PROCEDURE TEST_PROC LANGUAGE SQL
BEGIN
REFRESH TABLE MQT_TEST;
END;
--!!!! FAILS WITH THE FOLLOWING ERROR CODE: - DB2 Database Error :
ERROR [42601] [IBM][DB2/LINUXX8664] SQL0104N An unexpected token "REFRESH" was found following "ANGUAGE SQL BEGIN ". Expected tokens may include: "TRUNCATE" .
You can't execute the REFRESH TABLE as a static statement in a stored procedure as it can only run as a dynamic statement.
Therefore, the proper method to do this is to use the EXECUTE IMMEDIATE statement:
CREATE OR REPLACE PROCEDURE TEST_PROC
LANGUAGE SQL
BEGIN
declare vSQL varchar(1024);
set vSQL = 'refresh table MQT_TEST';
execute immediate vSQL;
END#

Resources