我创建了一个评估行的 UDF。在大多数情况下它工作正常,但有时它会表现得很奇怪。请参阅下面的示例。这些是完全相同的查询。一个有“限制”,另一个没有。此处的总记录数为 32,但我仅为示例添加了限制 1000。您知道为什么这两个查询的行为不同吗?
答案 0 :(得分:0)
功能代码:
create or replace function new_row_evaluator
(b varchar, m datetime, f DATETIME, t datetime )
returns string
language javascript
as '
if (typeof tmp_barcode === "undefined") {
tmp_barcode = B;
tmp_fromdate = F;
tmp_todate = T;
return "1";
}
if (tmp_barcode == B) {
if (M >= tmp_fromdate && M <= tmp_todate) {
return "0";
} else {
tmp_fromdate = F;
tmp_todate = T;
return "1";
}
} else {
tmp_barcode = B;
tmp_fromdate = F;
tmp_todate = T;
return "1";
} ';
我假设 UDF 正在使用某种全局状态 tmp_barcode
。
Snowflake 通常会在 UDF 的迭代之间保留 JavaScript 全局状态。 但是,您不应依赖先前对函数调用之间可用的全局状态的修改。此外,您不应假设所有行都将在同一 JavaScript 环境中执行。
推荐的模式是使用 JavaScript 的全局变量语义来保证相关代码只被评估一次。例如:
var setup = function() {
/* SETUP LOGIC */
};
if (typeof(setup_done) === "undefined") {
setup();
setup_done = true; // setting global variable to true
}
请注意,此机制仅对缓存代码评估的效果是安全的。不能保证初始化后所有行的全局上下文都会保留,并且没有业务逻辑应该依赖它。