【问题标题】:Snowflake Snowsql conditional breaking IF, SWITCHSnowflake Snowsql 条件中断 IF、SWITCH
【发布时间】:2025-11-27 11:20:05
【问题描述】:

问题是关于 Snowflake snowsql。并且需要进行条件检查以查看 ETL_Date 是否已插入表中以及是否已插入;退出存储过程。否则,如果未插入日期,则继续插入数据,然后返回成功(零)并退出。任何帮助将不胜感激。谢谢。

起点:到目前为止我所做的代码。

IF ((SELECT IFNULL(MAX(ETL_DATE),'1900-01-01') FROM DB.TABLES.test_20200909) > CURRENT_DATE() )
{RETURN 0; break;}
else insert into DB.TABLES.test_20200909 (ETL_DATE,INSERT_VALUE)
values(CURRENT_DATE(),1)

这给了我错误:SQL 编译错误:第 1 行语法错误,位置 0 意外'IF'。

目标/结束游戏:必须将其放入存储过程中。 到目前为止我所说的是:

CREATE or replace procedure   TABLE_DB.TABLES.test_20200909_1 ()
returns FLOAT
language javascript
as
$$

var test_1 =`IF ((SELECT MAX(ETL_DATE) FROM DB.TABLES.test_20200909) > CURRENT_DATE() )
{RETURN 0; break;}
else insert into DB.TABLES.test_20200909 (ETL_DATE,INSERT_VALUE)
values(CURRENT_DATE(),1)`;
var test_1_stmt =  snowflake.createStatement({sqlText: test_1});  
var test_1_res = test_1_stmt.execute();
return 0
$$

【问题讨论】:

    标签: snowflake-cloud-data-platform snowsql


    【解决方案1】:

    如果您的目标是创建一个存储过程来检查/管理您的负载,我会创建一个如下所示的:

    create or replace procedure SP_CHECK_LOAD()
        RETURNS VARCHAR(256) NOT NULL
        LANGUAGE JAVASCRIPT
        EXECUTE AS CALLER
    as $$    
    
    function get_check_load()
    {
        var v_out_check_load;
        rs = snowflake.execute ( { sqlText: `SELECT CASE WHEN MAX(ETL_DATE)>=CURRENT_DATE() THEN 0 ELSE 1 END AS CHECK_RESULT FROM DB.TABLES.test_20200909;` }  );
        if( rs.next())
        {
           v_out_check_load = rs.getColumnValue(1); // get check result
        }
    
        return v_out_check_load; 
    }   
      
      var result = new String('Successfully Executed');
      var v_check = get_check_load();
      
      if ( v_check==1 )
      {
        //data not yet loaded -> load them
        try {
           
        var sql_command = `INSERT INTO DB.TABLES.test_20200909 (ETL_DATE,INSERT_VALUE) VALUES(CURRENT_DATE(),1)`;
     
        var stmt = snowflake.createStatement({sqlText: sql_command});
        var res = stmt.execute();  
        
        }
        catch (err) {
        result =  "Failed: Code: " + err.code + " | State: " + err.state;
        result += "\n  Message: " + err.message;
        result += "\nStack Trace:\n" + err.stackTraceTxt; 
        } 
     } // end if
     
     return result;
    
      $$;
    

    请注意,我在检查条件 MAX(ETL_DATE)>=CURRENT_DATE() 中使用了 >= ,而不仅仅是在您的示例中使用 > 因为在这种情况下,您将排除当前日期加载.如果这不适合您的需要,请更改它。

    【讨论】:

    • 谢谢@Saul 我会试试这个。
    【解决方案2】:

    根据您所提到的,看起来您甚至不需要存储过程来执行此操作。您可以使用可能更容易设置的合并匹配

    并且需要进行条件检查以查看 ETL_Date 是否已经插入到表中以及是否已插入;退出存储过程。否则,如果没有插入日期,则继续插入数据,然后返回成功(零)

    请查看以下是否是您想要实现的目标

    CREATE OR REPLACE TABLE test_20200909(INSERT_VALUE NUMBER, ETL_DATE TIMESTAMP);
     
    INSERT INTO TEST_20200909 VALUES(1, '2020-09-01 00:00:00.000');
    INSERT INTO TEST_20200909 VALUES(1, '2020-09-02 00:00:00.000');
    INSERT INTO TEST_20200909 VALUES(1, '2020-09-03 00:00:00.000');
    INSERT INTO TEST_20200909 VALUES(1, '2020-09-04 00:00:00.000');
     
    SELECT * FROM test_20200909;
     
    MERGE INTO test_20200909 T
     USING(SELECT MAX(ETL_DATE) maxdate FROM test_20200909) S 
     ON S.maxdate=CURRENT_DATE()
     when NOT matched then 
      insert (INSERT_VALUE,ETL_DATE)  values (1, CURRENT_DATE());
      
    SELECT * FROM test_20200909;
    

    【讨论】:

    • 谢谢@Rajib;我也会试试这个。我很遗憾确实需要一个存储过程。由于我上面提出的解决方案是最基本的;在这个 IF 子句之后还有其他的选择逻辑语句可以实际插入到表中。
    • 当然你也可以在你的程序中嵌入这个合并查询,这将帮助你减少代码。让我们知道您最终是如何解决这个问题的。
    • 嗨,Rajib MERGE 也可以正常工作;是 MS-SQL 吗?将是我合并数据的唯一方法。可悲的是(我的意思是),我正在将代码迁移到 Snowflake。业务需要一个存储过程。