我知道,这是一个相当古老的线程,但是我的发现基于我在这里从 Jenova 读到的内容,对其他人来说可能很有趣。这就是为什么我把它们写下来。
我面临着同样的问题。用户可以在我必须优化的计算视图中的输入参数中发送多个条目。不幸的是,我以前遇到过像 Jenova 和其他人一样的问题。而且,不,恕我直言,这不是关于动态视图执行或动态 sql,而是关于在脚本计算视图或表函数中以干净的方式处理列表,如果它们是在输入参数中发送的。
Lars 使用 APPLY_FILTER 的建议不适用于我的情况,因为我不能在 APPLY_FILTER 函数本身中使用复杂的语句。我必须在选择中具体化全部数据,我可以将结果分配给 APPLY_FILTER 然后执行过滤。我希望看到在第一步中应用的过滤,而不是在实现未出现在过滤器应用程序结果中的数据之后。
因此,我使用 hdbtablefunction 创建了一个执行参数字符串清理和转换为数组的函数,然后它返回 UNNEST 函数的结果。
由于函数的结果是一个表,它可以用作脚本视图或表函数中的表 - 在连接、子选择等中。
通过这种方式,我能够按预期快速处理用户输入列表,并且资源消耗更少。
FUNCTION "_SYS_BIC"."package1::transparam" (ip_string NVARCHAR(500) )
RETURNS table ( "PARAMETER" nvarchar(100))
LANGUAGE SQLSCRIPT
SQL SECURITY INVOKER AS
v_test varchar(1000);
IP_DELIMITER VARCHAR(1) := ',';
v_out VARCHAR(100):='';
v_count INTEGER:=1;
v_substr VARCHAR(1000):='';
v_substr2 VARCHAR(1000):='';
id INTEGER array;
val VARCHAR(100) array;
BEGIN
--
v_substr:=:ip_string;
v_substr := REPLACE(:v_substr, '''', '');
v_substr := REPLACE(:v_substr, ' ', '');
while(LOCATE (:v_substr, :ip_delimiter) > 0 ) do
-- find value
v_out := SUBSTR(v_substr, 0, LOCATE (:v_substr, :ip_delimiter) - 1 );
-- out to output
val[v_count]:=v_out;
-- increment counter
v_count:=:v_count+1;
-- new substring for search
v_substr2 := SUBSTR(:v_substr, LOCATE (:v_substr, :ip_delimiter) + 1, LENGTH(:v_substr));
v_substr := v_substr2;
END while;
IF(LOCATE (:v_substr, :ip_delimiter) = 0 AND LENGTH(:v_substr) > 0) THEN
-- no delimiter in string
val[v_count]:=v_substr;
END IF;
-- format output as tables
rst = unnest(:VAL) AS ("PARAMETER");
RETURN SELECT * FROM :rst;
END;
可以称为
select * from "package1.transparam"('''BLU'',''BLA''')
用两行返回表
PARAMETER
---------
BLU
BLA