将日期转换为sfdate的雪花

时间:2020-06-29 05:17:17

标签: sql snowflake-cloud-data-platform

我在使用Snowflake的JavaScript处理Snowflake中的日期时遇到问题。

一个选择查询并获取日期。在源表中将其声明为日期。 我希望能够将此日期添加1天,然后将其插入另一个表的DATE字段中。但是,我在此上遇到绑定错误。在另一个stackoverflow的帮助下,我得到了返回 输入并发现它是一个字符串,而不是sfDate。

如何将选择的返回字符串转换为可以使用的日期?一个额外的问题是如何将这一天增加一天?

还尝试使用try_to_date将其转换为日期,如下所示:

                    var convertedRunningDate = Date("Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)");
                    statement = snowflake.createStatement(
                        {
                            sqlText: " insert into mytable(date_stamp)  values(try_to_date(?)) "
                            ,binds: convertedRunningDate 
                        }
                    );

并且没有它:

                    var convertedRunningDate = Date("Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)");
                    statement = snowflake.createStatement(
                        {
                            sqlText: " insert into mytable(date_stamp)  values(?) "
                            ,binds: convertedRunningDate 
                        }
                    );


我明白了

Invalid binds argumentSun Jul 29 2018 00:00:00 GMT-0700 (PDT). Error: Unsupported type for binding argument 2undefined

在两种情况下

1 个答案:

答案 0 :(得分:1)

默认的JavaScript Date.toString()表示形式将日期转换为字符串in a format that is non-standard。另外,要使用Date constructor,请确保您传递new关键字,否则Date的作用是拒绝无效输入并静默返回当前日期。

> console.log(Date("Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)"))
"Mon Jun 29 2020 01:16:31 GMT-0700 (PDT)"

> console.log(new Date("Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)"))
"Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)"

在使用SQL中JavaScript的默认日期字符串格式将其转换为日期或时间戳类型时,Snowflake仅识别标准格式的字符串,并将拒绝格式为Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)的JS日期字符串。改用Date.toISOString()来生成适用于Snowflake SQL类型的可用表示形式。

此外,snowflake.createStatement(…)中的binds参数必须始终是元素的数组,即使您打算只将单个元素传递给它。也就是说,提供binds: [convertedRunningDate]而不是binds: convertedRunningDate

结合以上两点,下面的示例演示了如何在JavaScript中将日期从一个表转移到另一个表。

create or replace table source_table(datecol date) as select current_date;

create or replace table dest_table (datecol date);

CREATE OR REPLACE PROCEDURE insert_date_plus_one() 
RETURNS boolean 
LANGUAGE JAVASCRIPT 
AS 
$$ 
    // Grab a datecol from a select query
    var source_date_stmt = snowflake.createStatement(
      {
        sqlText: "select datecol from source_table"
      }
    );
    var source_resultset = source_date_stmt.execute();
    source_resultset.next();
    
    // This is of type SfDate because it came from a query ResultSet,
    // so we can apply standard JS Date functions over it
    var source_date = source_resultset.getColumnValue(1);
    
    // Function to increment a Date object by one standard day
    // Sourced from https://stackoverflow.com/questions/563406/add-days-to-javascript-date
    function addDaysInJs(date, days) {
      var result = new Date(date);
      result.setDate(result.getDate() + days);
      return result;
    }
    
    var dest_date = addDaysInJs(source_date, 1);
    
    // Insert the incremented date using its ISO representation string
    // which will allow Snowflake to grok it properly
    var dest_date_stmt = snowflake.createStatement(
      {
        sqlText: "insert into dest_table values (?)"
        ,binds: [dest_date.toISOString()]
      }
    );
    var dest_resultset = dest_date_stmt.execute();
    var did_insert_run = dest_resultset.next();
    
    return did_insert_run;
$$ ;

call insert_date_plus_one();

这将产生结果:

> select * from source_table;
+------------+
| DATECOL    |
|------------|
| 2020-06-29 |
+------------+
> select * from dest_table;
+------------+
| DATECOL    |
|------------|
+------------+

> call insert_date_plus_one();
+----------------------+
| INSERT_DATE_PLUS_ONE |
|----------------------|
| TRUE                 |
+----------------------+

> select * from dest_table;
+------------+
| DATECOL    |
|------------|
| 2020-06-30 |
+------------+

如果您需要随意使用Date对象,而不是从表行中获取对象,只需确保您正确地构造了它们(使用new),并且在绑定时使用其Date.toISOString()方法,而不是按原样传递(默认toString()会产生不兼容的格式)。

注意:如果可能,请尝试通过SQL对其进行操作并仅提取结果,这样就不必使用两个不同的日期/时间类型的系统。

进一步阅读