雪花:函数“IFF”的参数类型无效:(VARCHAR(16777216), VARCHAR(16777216), VARCHAR(16777216)) At Statement.execute snowflake

时间:2021-03-03 05:08:08

标签: snowflake-cloud-data-platform

我在雪花中运行一个存储过程并且代码编译失败

Execution error in store procedure SP_POPULATE_SYS_AUDIT_DATA_BMC: SQL compilation error: error line 6 at position 2,776 Invalid argument types for function 'IFF': (VARCHAR(16777216), VARCHAR(16777216), VARCHAR(16777216)) At Statement.execute, line 150 position 61

以下是发生错误的代码片段

v_sql_3 = `insert into `+v_mds_db_name+`.`+v_source_table_name+`_temp
                        (sys_id, documentkey,tablename,fieldname,value, sys_created_on, action, sys_updated_on, sys_created_by ,
                            sys_updated_by, sourceinstance, cdctype,_numerify_batchid, cdchash, cdchash_sequence, cdctime, etl_run_number)
                        select concat(`+v_sys_id_field+`,'~',replace('`+v_field+`',' ','_')) as sys_id, 
                            original_request_id as documentkey,'`+v_source_table_name+`' as tablename, '`+v_field+`' as fieldname, 
                            
                            trim(replace(replace(`+v_sql_2+`concat(case when split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2) 
                                then substring(split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2),1,
                                position('(',split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2))-1) 
                                else split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2) end ,': '),
                                `+v_sql_1+`': ',''),'\n','')) as value, audit_date as sys_created_on, 
                            case when action = 4 then 'Create' when action = 2 then 'Set'  when action = 8 then  'Delete'  when action = 16 then  'Merge' end,
                            modified_date as sys_updated_on,submitter as sys_created_by, user as sys_updated_by,sourceinstance,cdctype as cdctype ,
                            _numerify_batchid, cdchash, cdchash_sequence, cdctime , `+v_etl_run_number+` 
                        from `+v_mds_db_name+`.`+v_mds_table_name+` 
                        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%'
                    union
                        select concat(`+v_sys_id_field+`,'~',replace('`+v_field+`',' ','_')) as sys_id, 
                            original_request_id as documentkey,'`+v_source_table_name+`' as tablename, '`+v_field+`' as fieldname,
                            trim(replace(replace(`+v_sql_2+`concat(case when split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2) REGEXP '.*\\([0-9]\\).*' 
                                then substring(split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2),1,
                                position('(',split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2))-1) 
                                else split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2) end ,': '),
                                `+v_sql_1+`': ',''),'\n','')) as value, audit_date as sys_created_on, 
                            case when action = 4 then 'Create' when action = 2 then 'Set'  when action = 8 then  'Delete'  when action = 16 then  'Merge' end,
                            modified_date as sys_updated_on,submitter as sys_created_by, user as sys_updated_by,sourceinstance,'X' as cdctype ,
                            _numerify_batchid, cdchash, cdchash_sequence, cdctime , `+v_etl_run_number+` 
                        from `+v_mds_db_name+`.`+v_audit_table_name+`_final 
                        where original_request_id in (select distinct original_request_id 
                                                        from `+v_mds_db_name+`.`+v_mds_table_name+` 
                                                        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%' ) 
                            and fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%'
                            and `+v_sys_id_field+` not in ( select  v_sys_id_field 
                                                        from `+v_mds_db_name+`.`+v_mds_table_name+` 
                                                        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%')`;
            
            snowflake.createStatement( { sqlText: v_sql_3} ).execute();

PS:我对雪花很陌生

2 个答案:

答案 0 :(得分:2)

问题是这一行

case when action = 4 then 'Create' when action = 2 then 'Set'  when action = 8 then  'Delete'  when action = 16 then  'Merge' end

末尾应该有一个 AS action 因为前一行是 sys_created_on 而后一行是 sys_updated_on

etl_run_number 行之后也应该命名。

所以如果我的编辑是正确的

s1 = 'split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2)';

v_sql_3 = `insert into `+v_mds_db_name+`.`+v_source_table_name+`_temp
        (sys_id, documentkey,tablename,fieldname,value, sys_created_on, 
        action, sys_updated_on, sys_created_by, sys_updated_by, 
        sourceinstance, cdctype,_numerify_batchid, cdchash, 
        cdchash_sequence, cdctime, etl_run_number)
        select concat(`+v_sys_id_field+`,'~',replace('`+v_field+`',' ','_')) as sys_id, 
            original_request_id as documentkey,
            '`+v_source_table_name+`' as tablename,
            '`+v_field+`' as fieldname,
            trim(replace(replace(`+v_sql_2+`concat(
                case when '+s1+' IS NOT NULL
                then substring('+s1+',1,position('(','+s1+')-1) 
                else '+s1+' end ,': '),
                `+v_sql_1+`': ',''),'\n','')) as value,
            audit_date as sys_created_on, 
            case when action = 4 then 'Create' when action = 2 then 'Set'  when action = 8 then  'Delete'  when action = 16 then  'Merge' end as action,
            modified_date as sys_updated_on,
            submitter as sys_created_by, 
            user as sys_updated_by,
            sourceinstance,
            cdctype as cdctype,
            _numerify_batchid, 
             cdchash,
             cdchash_sequence, 
             cdctime , 
             `+v_etl_run_number+` as etl_run_number 
        from `+v_mds_db_name+`.`+v_mds_table_name+` 
        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%'
    union
        select concat(`+v_sys_id_field+`,'~',replace('`+v_field+`',' ','_')) as sys_id, 
            original_request_id as documentkey,
            '`+v_source_table_name+`' as tablename,
            '`+v_field+`' as fieldname,
            trim(replace(replace(`+v_sql_2+`concat(case when '+s1+' REGEXP '.*\\([0-9]\\).*' 
                then substring('+s1+',1,
                position('(','+s1+')-1) 
                else '+s1+' end ,': '),
                `+v_sql_1+`': ',''),'\n','')) as value,
            audit_date as sys_created_on, 
            case when action = 4 then 'Create' when action = 2 then 'Set'  when action = 8 then  'Delete'  when action = 16 then  'Merge' end as action,
            modified_date as sys_updated_on,
            submitter as sys_created_by,
            user as sys_updated_by,
            sourceinstance,
            'X' as cdctype ,
            _numerify_batchid, 
            cdchash, 
            cdchash_sequence, 
            cdctime , 
            `+v_etl_run_number+` as etl_run_number 
        from `+v_mds_db_name+`.`+v_audit_table_name+`_final 
        where original_request_id in (select distinct original_request_id 
                                        from `+v_mds_db_name+`.`+v_mds_table_name+` 
                                        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%' ) 
            and fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%'
            and `+v_sys_id_field+` not in ( select  v_sys_id_field 
                                        from `+v_mds_db_name+`.`+v_mds_table_name+` 
                                        where fields_changed like '%;`+v_field+`;%' and log like '%`+v_field_lookup+`%')`;
    
        snowflake.createStatement( { sqlText: v_sql_3} ).execute();

应该是你想要的。

我提取了

split_part(substring(log,position('`+v_field_lookup+`',log)+`+v_field_length+`),': ',2)

放入一个名为 s1 的变量中以使其更具可读性,因为它被大量重复。

答案 1 :(得分:0)

这里的问题是,与 MySQL 相比:

select IF(1,TRUE,FALSE); -- this works

但在雪花中:

select IFF(1,TRUE,FALSE); -- this fails

相反,正确的方法是

select IFF(1= 1,TRUE,FALSE); -- this works

因此,无论是 case 还是 IFF,都必须根据某个真值对其进行评估,否则编译失败

同样是上面提到的代码案例中的问题,当没有对任何事物进行两次评估时,因此出现错误