【问题标题】:Executing a SQL statement, present in a table, and returning the resulting record set in Snowflake执行 SQL 语句,出现在表中,并在 Snowflake 中返回结果记录集
【发布时间】:2020-07-10 04:05:38
【问题描述】:

我需要一个实际场景的帮助。我在 Snowflake 中有一个名为 CONFIG_TBL 的表。该表有 SQL 语句,每行 1 个。我的目标是使用 Snowflake 存储过程或 Snowflake UDF,或两者的组合,并返回执行该语句后将获得的结果集。

这些语句是简单的选择语句,例如“select * from ABC”。

我本可以在 SQL Server 中非常轻松地做到这一点,因为过程可以返回表值。但是,我不知道如何在 Snowflake 中执行此操作。

任何帮助将不胜感激。

提前致谢。

【问题讨论】:

  • 选择会产生多少行?您不能从 Snowflake 存储过程返回表,但可以返回带分隔符的字符串或 JSON 最大 16 mb 的变体。
  • 这确实是一个限制!我要返回的数据超过16mb。
  • 在这种情况下最好的办法是将其写入临时表。如果您需要代码示例,请告诉我。

标签: snowflake-cloud-data-platform


【解决方案1】:

这至少可以帮助您入门。过程使用 javascript(SQL 存储过程即将推出),但它们可用于运行您正在寻找的动态查询。

您可以通过多种方式获得结果。通过返回变体对象或在调用过程后使用 result_scan。

此示例仅运行一个查询,因此您的最终解决方案将根据您希望输出的外观而有所不同。

CREATE OR REPLACE PROCEDURE SCHEMA.PROCEDURE_NAME()
RETURNS VARIANT
LANGUAGE JAVASCRIPT
EXECUTE AS CALLER
AS $$
retrieve_queries_sql = "select top 1 query from CONFIG_TBL";
retrieve_queries_result_set = snowflake.execute({sqlText: retrieve_queries_sql });

query_to_run = retrieve_queries_result_set.next().getColumnValue(1);

rs = snowflake.execute({sqlText: query_to_run})

var return_value = "";
if (rs.next())  {
      return_value += rs.getColumnValue(1);
      return_value += ", " + rs.getColumnValue(2);
      }
while (rs.next())  {
      return_value += "\n";
      return_value += rs.getColumnValue(1);
      return_value += ", " + rs.getColumnValue(2);
      }
  }
return return_value;
$$

CALL SCHEMA.PROCEDURE_NAME()

SELECT *
FROM table(result_scan(last_query_id()))

编辑:修复了让示例正确返回结果,然后 result_scan 可以使用该结果。示例取自 here。还有更多从过程中获取结果的示例,包括使用 JSON 输出。

【讨论】:

  • 使用 result_scan 似乎无法访问在存储过程中运行的查询。它将生成一个错误 Statement not found。可行的方法是创建一个临时表,因为它会在会话的生命周期内继续存在。
  • 谢谢。我忘记了一段代码。这个例子来自 Snowflake Docs。
  • 啊...我看到他们在示例中做了什么。他们使用 result_scan 来获取和使用存储过程的输出。这仍然将输出限制为 16mb,并且不是基于表的。引用在存储过程中运行的查询的 result_scan 会很好(与本示例中的输出相比),但由于某些原因不起作用。
  • 如果你作为调用者执行它可以工作,但你可能需要使用 last_query_id(-1) 或以其他方式获取 query_id。
  • 嗨@DavidGarrison,非常感谢您的宝贵意见。 last_query_id(-1), (在我的情况下为-2)似乎完全按照我的意愿工作,在 result_scan 中使用它给了我我需要的东西。出色的解决方案。根据您的输入,解决方案似乎如下.. 调用 stored_proc(inputs); SELECT * FROM table(result_scan(last_query_id(-2)));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多