在存储过程中为 null 时处理动态参数
Handle dynamic parameter when null in the stored procedure
我在 redshift 中处理存储过程。我看到当传递的参数是 NULL
到存储过程中的 Execute 语句时。它因 cannot execute a null string
.
而失败
请告诉我如何解决问题。
存储过程:
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||'''';
有两个变量可以为 NULL - iter.code
或 cond_holder.condition
。 cond_holder.condition
被 NVL
包裹,但 NVL
在结果字符串中,而不是在生成表达式中。
第二大问题是针对 SQL 注入的漏洞。也许你应该这样做:
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 = '
USING iter.code;
我不确定 Redshift 是否支持 USING
子句。如果没有,那么你应该使用 quote_literal
函数:
'... where code = ' || quote_literal(iter.code);
我在 redshift 中处理存储过程。我看到当传递的参数是 NULL
到存储过程中的 Execute 语句时。它因 cannot execute a null string
.
请告诉我如何解决问题。
存储过程:
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||'''';
有两个变量可以为 NULL - iter.code
或 cond_holder.condition
。 cond_holder.condition
被 NVL
包裹,但 NVL
在结果字符串中,而不是在生成表达式中。
第二大问题是针对 SQL 注入的漏洞。也许你应该这样做:
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 = '
USING iter.code;
我不确定 Redshift 是否支持 USING
子句。如果没有,那么你应该使用 quote_literal
函数:
'... where code = ' || quote_literal(iter.code);