简体   繁体   English

将日期转换为雪花的 sfdate

[英]Convert date into sfdate for snowflake

I'm having problems working with dates in Snowflake using Snowflake's Javascript.我在使用 Snowflake 的 Javascript 处理 Snowflake 中的日期时遇到问题。

One select queries and gets a date.一个 select 查询并获取日期。 It's declared in the source table as a date.它在源表中声明为日期。 I want to be able to add 1 day to this date, then insert that into a DATE field in another table.我希望能够将 1 天添加到该日期,然后将其插入到另一个表的 DATE 字段中。 However, I'm getting a bind error on this.但是,我收到了一个绑定错误。 With help from another stackoverflow, I got the returned type and found it to be a string, and not an sfDate.在另一个 stackoverflow 的帮助下,我得到了返回的类型,发现它是一个字符串,而不是 sfDate。

How can I convert the returned string from a select into a date that I can work with?如何将返回的字符串从 select 转换为我可以使用的日期? A bonus question is how can I add one day to this value?一个额外的问题是我怎样才能在这个值上增加一天?

Also tried to convert it to date with try_to_date as below:还尝试使用 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 
                        }
                    );

and without it:没有它:

                    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 
                        }
                    );


and I get我得到

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

in both cases在这两种情况下

The default JavaScript Date.toString() representation converts the date to a string in a format that is non-standard .默认的 JavaScript Date.toString()表示将日期转换为非标准格式的字符串。 Also, to use a Date constructor ensure you pass the new keyword as otherwise Date acts as a function that rejects invalid inputs and silently returns the current date.此外,要使用Date构造函数,请确保传递new关键字,否则Date充当 function 拒绝无效输入并静默返回当前日期。

> 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)"

When using the default Date string formatting from JavaScript in SQL to be cast as date or timestamp types, Snowflake only recognises standard formatted strings, and will reject JS date strings of the form Sun Jul 29 2018 00:00:00 GMT-0700 (PDT) .当使用 SQL 中 JavaScript 的默认日期字符串格式以转换为日期或时间戳类型时,Snowflake 仅识别标准格式的字符串,并将拒绝Sun Jul 29 2018 00:00:00 GMT-0700 (PDT)形式的 JS 日期字符串Sun Jul 29 2018 00:00:00 GMT-0700 (PDT) . Use Date.toISOString() instead to produce a usable representation that will work with Snowflake SQL types.请改用Date.toISOString()来生成可与 Snowflake SQL 类型一起使用的可用表示。

Furthermore, the binds argument in snowflake.createStatement(…) must always be an array of elements , even when you are planning to pass only a single element to it.此外, snowflake.createStatement(…)中的 binds 参数必须始终是一个元素数组,即使您打算只向它传递一个元素。 That is, supply binds: [convertedRunningDate] instead of binds: convertedRunningDate .也就是说,提供binds: [convertedRunningDate]而不是binds: convertedRunningDate

Combining the two above points, here's an example that shows how to manipulate the date within JavaScript from one table to another.结合上述两点,这里有一个示例,展示了如何在 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();

This yields the result:这会产生结果:

> 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 |
+------------+

If you need to arbitrarily use Date objects instead of sourcing it from a table row, just ensure you are constructing them properly (with new ), and when binding use its Date.toISOString() method instead of passing it as-is (default toString() produces an incompatible format).如果您需要任意使用Date对象而不是从表行中获取它,只需确保您正确构建它们(使用new ),并且在绑定时使用它的Date.toISOString()方法而不是按原样传递它(默认toString()产生不兼容的格式)。

Note : Where possible, try to manipulate it over SQL and just extract results so you do not have to work with two different date/time type systems.注意:在可能的情况下,尝试通过 SQL 对其进行操作,然后仅提取结果,这样您就不必使用两种不同的日期/时间类型系统。

Further reading :进一步阅读

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM