I working on a stored procedure in redshift. I see that when parameters passed are NULL to the Execute statement in stored procedure. It fails with cannot execute a null string.
Please give me insights on how to solve the problem.
Stored Procedure:
CREATE OR REPLACE PROCEDURE outer_proc() LANGUAGE plpgsql
AS $$
DECLARE
cond_holder RECORD;
iter RECORD;
BEGIN
drop table if exists tmp_direction_comms;
create temporary table tmp_direction_comms as select distinct code from direction_coms;
DROP TABLE if exists final_direction_comms;
EXECUTE 'CREATE TEMP TABLE final_direction_comms
(
code varchar(100),
direction varchar(100),
dir_flg Boolean
)';
FOR iter IN select code from tmp_direction_comms LOOP
RAISE INFO 'code is %', iter.code;
SELECT INTO cond_holder distinct condition FROM mapping where code = iter.code;
RAISE INFO 'engmnt_cd is %', cond_holder.condition;
EXECUTE 'INSERT INTO final_direction_comms select code, direction, case when NVL('||cond_holder.condition||',false) then true else false end as dir_flg
from direction_coms where code = '''||iter.code||'''';
END LOOP;
END;
$$;
EXECUTE 'INSERT INTO final_direction_comms select code, direction,
case when NVL('||cond_holder.condition||',false) then true else false end as dir_flg
from acp_edw.stg_edw.direction_coms where code = '''||iter.code||'''';
There are two variables that can be NULL - iter.code or cond_holder.condition. The cond_holder.condition is wrapped by NVL, but NVL is inside in result string, not in generating expression.
Second big issue is a vulnerability against SQL injection. Probably you should to do:
EXECUTE 'INSERT INTO final_direction_comms select code, direction,
case when ' || NVL(cond_holder.condition, false) ' || then true else false end as dir_flg
from acp_edw.stg_edw.direction_coms where code = $1'
USING iter.code;
I am not sure if Redshift has support for USING clause. If not, then you should to use quote_literal function:
'... where code = ' || quote_literal(iter.code);
Related
I ve checked this "SQLCODE=-104, SQLSTATE=42601" this Error code but still not able to find what wrong with above proc.
I also execute the query and it worked fine. the below error I got when I run proc.
** SQLCODE=-104, SQLSTATE=42601, SQLERRMC=select Con_Gruop_Name from;t vparam = grpName; ;**
create OR REPLACE PROCEDURE getConGroup(in grpName varchar(100))
begin
declare vparam varchar(100);
set vparam = grpName;
select Con_Gruop_Name from Grp_Table where Gruop_Name=vparam;
end
1) verify Con_Gruop_Name and Gruop_Name is correct name, i suppose its Con_Group_Name and Group_Name
2) You can use parameter directly into your query
3) You must use cursor for return result select, like this
4) May be you should be add Library into your select " ... from yourlib.yourtable where ..."
CREATE PROCEDURE getConGroup (IN grpName varchar(100))
RESULT SETS 1
LANGUAGE SQL
P1: BEGIN
DECLARE cursor1 CURSOR WITH RETURN FOR
select Con_Gruop_Name from Grp_Table where Gruop_Name=grpName ;
OPEN cursor1;
END P1
I have a giant mysql sql dump file. But I'm getting error when I try to import it because of foreign key checks. Somehow there is missing data, so I'm importing it with
SET SESSION FOREIGN_KEY_CHECKS=0;
and it works, but I'm looking for a solution for missing data.
So is there any automatic way to find and delete relation data with missing entries to get a clean database dump, or I have to go and write manuel SQL for every relation, write query to delete missing values ?
You can automate a delete statement like this:
DELIMITER $$
DROP PROCEDURE IF EXISTS check_foreign $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `check_foreign`()
BEGIN
DECLARE finishing INTEGER DEFAULT 0;
DECLARE vstmt VARCHAR(4000);
DECLARE vtbname VARCHAR(50);
DECLARE vtbnameref VARCHAR(50);
DECLARE vtbcol VARCHAR(50);
DECLARE vtbcolref VARCHAR(50);
DECLARE cr_tables CURSOR FOR select a.table_name, a.referenced_table_name, a.column_name, a.referenced_column_name from information_schema.KEY_COLUMN_USAGE a where a.table_schema = 'protocol_manager' and a.REFERENCED_TABLE_NAME is not null order by a.table_name;
DECLARE CONTINUE HANDLER FOR not found SET finishing = 1;
OPEN cr_tables;
SET vstmt = '';
table_foreign_delete: loop
if finishing = 1 then
leave table_foreign_delete;
end if;
FETCH cr_tables INTO vtbname, vtbnameref, vtbcol, vtbcolref;
SET vstmt = CONCAT(vstmt, char(10), 'DELETE FROM ', vtbname, ' a WHERE NOT EXISTS (SELECT 1 FROM ', vtbnameref, ' b WHERE a.', vtbcol, ' = b.', vtbcolref, ');');
end loop table_foreign_delete;
select vstmt;
END$$
DELIMITER ;
You can even do deep search to find a way to execute it dynamicly. For example a temporary table with a trigger. You generate a delete statement, insert it into the temp table, trigger the insert that fires a another (func, proc) to execute the statement generated.
I am facing a tricky problem while I am trying to run stored procedure via Squirrel against DB2 database.
In the stored procedure have part where combine an sql statement like this:
SET V_SQL = 'SELECT DISTINCT ' || PARAM_COLUMNNAME || ' FROM '||PARAM_TABLENAME||' WHERE '||PARAM_COLUMNNAME||'<'||PARAM_NUMBER||';';
I changed the session statement paramater ; --> # to run properly the procedure call, but I get error message:
An unexpected token "" was found following "". Expected tokens may
include: "WHERE REP_ID<201506".. SQLCODE=-104, SQLSTATE=42601,
DRIVER=3.59.81 SQL Code: -104, SQL State: 42601
I guessed it is because of the delimeter ';' of the inside sql script so I changed the code like this:
SET V_SQL = 'SELECT DISTINCT ' || PARAM_COLUMNNAME || ' FROM '||PARAM_TABLENAME||' WHERE '||PARAM_COLUMNNAME||'<'||PARAM_NUMBER||'#';
Then I get this message:
The numeric literal "201506#" is not valid.. SQLCODE=-103,
SQLSTATE=42604, DRIVER=3.59.81 SQL Code: -103, SQL State: 42604
Do you have any idea?
Squirrel: SQuirreL SQL Client snapshot-20150623_2101 DB2: 9.5
Thanks and Cheers.
So finally what for me worked it was the comment sign:
SET V_SQL = 'SELECT DISTINCT ' || PARAM_COLUMNNAME || ' FROM '||PARAM_TABLENAME||' WHERE '||PARAM_COLUMNNAME||'<'||PARAM_NUMBER||';';--
The explanation I am not sure why pass through in this way the database engine, but worked.
Thanks!
I'm looking for help with a stored procedure in teradata. I want to update a whole table and for this I'm trying to use a for loop cursor. the problem is that my update is defined via column names passing through parameters to the SP.
I've seen it can be possible to use dynamic sql to do that but I haven't found any information on the subject concerning for loop cursor and dynamic sql. Is it possible with FOR LOOP CURSOR ?
I've tried to do only the select and calculs with dynamic sql, it works fine but then the problem is to update the table from the cursor on the select. In this case how to update a table from my cursor?
I let you show my code.
loop cursor :
REPLACE PROCEDURE [database].calDELAI
(
IN dateDebut VARCHAR(30),
IN dateFin VARCHAR(30),
IN delay VARCHAR(30)
)
BEGIN
DECLARE DATE_DEBUT_COLONNE VARCHAR(64);
DECLARE DATE_FIN_COLONNE VARCHAR(64);
SET DATE_DEBUT_COLONNE=dateDebut;
SET DATE_FIN_COLONNE=dateFin;
FOR for_loop_update AS cur_select_set CURSOR FOR
SELECT
TMP.DATE_FIN_COLONNE-TMP.DATE_DEBUT_COLONNE
FROM [database].ORD_T_DETL_ORDR_DELAI AS TMP
/* the select is more complicated but here is the spirit of it.*/
DO
IF (delay='DELAI1') THEN SET DELAI1=NB_JR_OUVRABLE;
END IF;
END FOR ;
END ;
The errors given by teradata are :
SPL1027:E, Missing/Invalid SQL statement'E(3810):Column/Parameter '[database].TMP.DATE_FIN_COLONNE' does not exist.'.
SPL2001:E, Undefined symbol 'DELAI1'.
SPL2001:E, Undefined symbol 'NB_JR_OUVRABLE'.
Thanks in advance for your replies and your help.
The call statement should contain all the input Paramenters , make sure you are specifying all the input parameters correctly. Could you please provide your call statement.
I have following problem formatting the #p_f_field variable correct, I get the error:
Could not execute statement.
Incorrect syntax near ‘+’
Sybase error code=102, SQLState=”42000”
Severity Level=15, State=181, Transaction State=1
Line 7
My stored procedure:
create proc dbo.sp_m_efi_dw_full_dsa_table_load_im ( -- parameter examples:
#p_skm_name varchar(4096),
#p_usr_name varchar(4096),
#p_t_name_dsa varchar(4096),
#p_t_name_bas varchar(4096),
#p_f_name varchar(4096),
#p_f_field varchar(4096)
)
as begin
declare #sql varchar(4096)
if #p_skm_name is not null
begin
if #p_usr_name is not null
begin
set #sql='TRUNCATE TABLE '+#p_skm_name+'.'+#p_usr_name+'.'+#p_t_name_dsa
exec (#sql)
end
end
set #sql='INSERT INTO '+#p_skm_name+'.'+#p_usr_name+'.'+#p_t_name_dsa+' '+#p_f_name+
' VALUES '+#p_f_field
exec (#sql)
end
My call to the stored procedure:
execute BAS_efi.dbo.sp_m_efi_dw_full_dsa_table_load_im
#p_skm_name = 'B_ef',
#p_usr_name = 'dbo',
#p_t_name_dsa = 'a_log',
#p_t_name_bas = 'a_log',
#p_f_name = '(NEWFIELD1)',
#p_f_field = '('+char(39)+'daf9af01-6bc2-11e-b23182b0623e'+char(39)+')'
Any suggestions on how to format the variable #p_f_field correct, or any others suggestions on how to execute this simple INSERT INTO procedure?