如何替换 snowflake.execute 语句中的循环结果?
Posted
技术标签:
【中文标题】如何替换 snowflake.execute 语句中的循环结果?【英文标题】:How to replace loop results inside snowflake.execute statement? 【发布时间】:2021-01-15 14:13:00 【问题描述】:我正在寻找一种方法来迭代具有列 id1、id2 的结果集并传递要在内部查询中使用的结果集列值,如下所示。
结果集的变量
列 1 列2例如:
select * from months cross join (select column1 AS "id1",column2 AS "id2")
Select "GEOGRAPHY" from mytable WHERE id1 = column1 and id2 = column2
但是,当我执行存储过程时,我遇到了以下错误。任何指针都非常感谢。谢谢
错误:
存储过程 TEST_PROC_STMT 中的执行错误:SQL 编译错误:错误第 8 行,位置 81 无效标识符 'COLUMN2' At Snowflake.execute,第 14 行位置 10
完整查询
create or replace procedure TEST_PROC_STMT()
returns varchar not null
language javascript
EXECUTE AS CALLER
as
$$
var distinct_sql_command = "select distinct id1, id2 from mytable ";
var statement1 = snowflake.createStatement( sqlText: distinct_sql_command );
var result_set1 = statement1.execute();
// Loop through the results, processing one row at a time...
while (result_set1.next())
var column1 = result_set1.getColumnValueAsString(1);
var column2 = result_set1.getColumnValueAsString(2);
snowflake.execute( sqlText: `
INSERT INTO mytable("GEOGRAPHY")(
Select * from (
with months as (
select dateadd(month, seq4(), '2020-02-01') "REPORTING MONTH" from table (generator(rowcount => 12))
), months_ids as (
select * from months cross join (select column1 AS "id1",column2 AS "id2")
) ,
event_months as (
Select * from (Select *,ROW_NUMBER() OVER (PARTITION BY id1,id2 ORDER BY "REPORTING MONTH") As rn FROM mytable) Where rn =1
) ,
final as (
select "REPORTING MONTH",id1,id2
, (select array_agg("GEOGRAPHY") within group (order by "REPORTING MONTH" desc) from mytable where a."REPORTING MONTH">="REPORTING MONTH" and a.id1=id1
from months_ids a order by "REPORTING MONTH"
)
Select a."GEOGRAPHY" from final a left join event_months b on a.id1=b.id1 and a.id2 = b.id2 where a."REPORTING MONTH" > b."REPORTING MONTH"
Except
Select "GEOGRAPHY" from mytable WHERE id1 = column1 and id2 = column2
)
)
`);
return "success";
$$
;
CALL TEST_PROC_STMT();
【问题讨论】:
【参考方案1】:代码至少有两个问题。首先,“var”定义了一个变量,它是一次性操作。在这种情况下,需要将其移出 while 循环:
// Loop through the results, processing one row at a time...
while (result_set1.next())
var column1 = result_set1.getColumnValueAsString(1);
var column2 = result_set1.getColumnValueAsString(2);
这是一个简单的解决方法:
// Loop through the results, processing one row at a time...
var column1;
var column2;
while (result_set1.next())
column1 = result_set1.getColumnValueAsString(1);
column2 = result_set1.getColumnValueAsString(2);
另一个问题是代码将“column2”指定为 SQL 中的文字列名,而不是变量。您可以告诉这一点,因为错误消息将变量名称大写,因此 Snowflake 正在寻找“COLUMN2”但找不到它。还有一个“column1”的用法,它应该是一个替换变量。
您可以通过将其设为替换变量来解决此问题。更改这两行:
select * from months cross join (select column1 AS "id1",column2 AS "id2")
...还有这个...
Select "GEOGRAPHY" from mytable WHERE id1 = column1 and id2 = column2
到这里:
select * from months cross join (select $column1 AS "id1", $column2 AS "id2")
...还有这个...
Select "GEOGRAPHY" from mytable WHERE id1 = column1 and id2 = $column2
请注意,当您使用反引号定义字符串时,$replacement_variable 语法仅适用于 JavaScript。当使用单引号或双引号终止字符串时,它将不起作用。
超过这两个可能会暴露其他人,但可以让它运行。
【讨论】:
以上是关于如何替换 snowflake.execute 语句中的循环结果?的主要内容,如果未能解决你的问题,请参考以下文章
如何使ibatis记录完整的SQL语句,而不仅仅是用'?'替换参数