使用 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 信息的正确值
答案 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