雪花查询不返回时区信息

时间:2021-02-24 11:51:35

标签: ruby jdbc odbc snowflake-cloud-data-platform

使用 Snowflake JDBC 和 Ruby ODBC 驱动程序查询时,带有时区元素的时间戳值未正确返回。

当雪花中的数据类型为 timestamp_ltz、timestamp_ntz、timestamp_tz 类型时,有没有办法添加额外的库来获取结果集中的区域信息。

import java.sql.*;
import java.util.Properties;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import net.snowflake.client.core.QueryStatus;
import net.snowflake.client.jdbc.SnowflakeResultSet;
import net.snowflake.client.jdbc.SnowflakeStatement;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import static java.sql.DriverManager.*;

public class SnowFlakeIntegration {
    public static void main(String[] args)
            throws Exception {
        String url = "jdbc:snowflake://mysnowflakeacc.snowflakecomputing.com?allowMultiQueries=true";
        Properties prop = new Properties();
        prop.put("user", "query_user");
        prop.put("password", "mypassword");
        prop.put("role", "myrole");

        try (Connection conn = getConnection(url, prop)) {
            Statement stat = conn.createStatement();
            String query2 = "select Now() as now_function, at_timezone(Now(),'America/Denver') as denver, at_timezone(Now(),'Asia/Kolkata') as India;";
            ResultSet resultSet = stat.unwrap(SnowflakeStatement.class).executeAsyncQuery(query2);
            QueryStatus queryStatus = QueryStatus.RUNNING;
            while (queryStatus == QueryStatus.RUNNING) {
                Thread.sleep(200); // 2000 milliseconds.
                queryStatus = resultSet.unwrap(SnowflakeResultSet.class).getStatus();
            }
            System.out.println(queryStatus);
            if (queryStatus != QueryStatus.FAILED_WITH_ERROR) {
                if (queryStatus != QueryStatus.SUCCESS) {
                    System.out.println("ERROR: unexpected QueryStatus: " + queryStatus);
                } else {
                    JSONArray json = new JSONArray();
                    ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                    ResultSet rs = stat.getResultSet();
                    System.out.println("\n");
                    while (rs.next()) {
                        int numColumns = resultSetMetaData.getColumnCount();
                        JSONObject obj = new JSONObject();
                        for (int i = 1; i <= numColumns; i++) {
                            String column_name = resultSetMetaData.getColumnName(i);
                            obj.put(column_name, rs.getObject(column_name));
                        }
                        json.add(obj);
                    }
                    System.out.println(json);
                }
            } else {
                System.out.format(
                        "ERROR %d: %s%n", queryStatus.getErrorMessage(), queryStatus.getErrorCode());
            }
            conn.close();
        }
    }

}

输出

[{"NOW_FUNCTION":2021-02-24 16:16:19.642,"DENVER":2021-02-24 04:46:19.642,"INDIA":2021-02-24 04:46:19.642}]

从 Snowflake Console 或 DB 执行的相同查询返回带有 ZOne 信息的正确值

enter image description here

1 个答案:

答案 0 :(得分:0)

首先,如果你想返回带时区信息的时间戳,你的UDF函数应该返回带时区的时间戳。我不知道您是否更改了“TIMESTAMP_TYPE_MAPPING”,但是当我测试您的 UDF 时,我看到它们返回 TIMESTAMP_NTZ 值。

https://docs.snowflake.com/en/sql-reference/parameters.html#timestamp-type-mapping

如果您的查询返回带时区信息的数据,您可以使用 getString 方法而不是 getObject 来读取带时区的时间戳:

System.out.println("reading the value: " + resultSet.getString(1));
System.out.println("reading the value: " + resultSet.getString(1));

reading the value: 2021-03-02 13:40:56.873
reading the value: 2021-03-02 13:40:56.873000000 +0300