这适用于Linux上的Informix 11.70.FC6GE。
假设表mytable
列value varchar(16)
,函数如下:
create function myfunc(str varchar(16)) returning varchar(16)
define result varchar(16);
while (<some-condition>)
let result = ...;
return result with resume;
end while;
end function;
当我这样做时
select * from mytable, table(myfunc(value)) vt(result);
我得到了
Not implemented yet. [SQL State=IX000, DB Errorcode=-999]
... - : - S。
否则
select * from mytable, table(myfunc('some literal')) vt(result);
作品。
有没有机会在给定的环境中实现这一目标?如果没有:我需要切换到哪个版本的Informix?
答案 0 :(得分:0)
我认为没有办法做你想做的事;我确信没有一种简单的方法可以做类似的事情。
考虑一个包含两个表的数据库:(化学)元素表 - 周期表 - 以及(美国)状态表。
CREATE TABLE elements
(
atomic_number INTEGER NOT NULL PRIMARY KEY
CHECK (atomic_number > 0 AND atomic_number < 120),
symbol CHAR(3) NOT NULL UNIQUE,
name CHAR(20) NOT NULL UNIQUE,
atomic_weight DECIMAL(8, 4) NOT NULL,
pt_period SMALLINT NOT NULL
CHECK (pt_period BETWEEN 1 AND 7),
pt_group CHAR(2) NOT NULL
-- 'L' for Lanthanoids, 'A' for Actinoids
CHECK (pt_group IN ('1', '2', 'L', 'A', '3', '4', '5', '6',
'7', '8', '9', '10', '11', '12', '13',
'14', '15', '16', '17', '18')),
stable CHAR(1) DEFAULT 'Y' NOT NULL
CHECK (stable IN ('Y', 'N'))
);
CREATE TABLE US_States
(
code CHAR(2) NOT NULL PRIMARY KEY,
name VARCHAR(15) NOT NULL UNIQUE
);
我假设您可以使用正确的数据填充这两个表(请参阅Web Elements了解周期表; Informix演示数据库'stores'有一个与{{1}同构的表state
这里使用的表)。
现在考虑一个程序US_States
:
states_starting()
我对CREATE FUNCTION states_starting(initial CHAR(1)) RETURNING VARCHAR(15);
DEFINE result VARCHAR(15);
FOREACH SELECT Name
INTO result
FROM US_States
WHERE Code[1] = initial
ORDER BY Name
RETURN result WITH RESUME;
END FOREACH;
END FUNCTION;
符号有效感到有些惊讶 - 但确实如此,指定了表别名vt(result)
和列名vt
。因此,适用的查询是:
result
这将生成118个元素和8个状态的笛卡尔积,其名称以“M”开头,总共944行。稍微合理的查询是:
SELECT *
FROM Elements, TABLE(states_starting('M')) vt(result)
这会产生6种元素的结果(镁, 锰, 䥑, 钔, 钼, Moscovium:Mercury没有计算,因为它的符号是Hg,它不是以M)和8个状态开始,如48行一样。
要执行的查询的调整类似于:
SELECT *
FROM Elements JOIN TABLE(states_starting('M')) AS vt(result)
ON Elements.Symbol[1] = vt.result[1]
ORDER BY Elements.Atomic_Number
然而,这不起作用,产生错误:
SELECT *
FROM Elements AS e
JOIN TABLE(states_starting(e.name[1])) AS vt(result)
ON Elements.Symbol[1] = vt.result[1]
ORDER BY Elements.Atomic_Number
这与问题中的错误不同;我无法复制它。但这是该查询面临的问题的症状。
问题是在-217: Column (name) not found in any table in the query (or SLV is undefined).
中,名称TABLE(…)
未知,但从参数中删除e
并不会改变事情。
此外,要生成完整的“正确”结果,必须多次评估e.
表达式,每个单独的首字母一次。因此,您需要使用不同参数在TABLE(…)
表达式中对函数进行多次调用的一组表结果。但这不是SQL在SQL中的工作方式。它们应该是“固定的”。函数的常量参数产生一个结果集,看起来像一个表。但是尝试使用不同的参数多次调用它并处理结果集(最多)会很棘手 - 这不是SQL的工作方式。
我对解释并不完全满意。我试图表达的想法几乎可以肯定是查询不起作用的原因,但我很高兴我已经解释得很好。
我尝试了多种变体。例如,假设您创建GROUP_CONCAT
aggregate,则可能需要尝试:
TABLE(…)
但这会产生:
SELECT group_concat(states_starting(a))
FROM (SELECT DISTINCT NAME[1] AS a FROM us_states)
GROUP BY a
我不认为从函数结果创建SET或LIST会有所帮助。
在Mac OS X 10.11.5上使用Informix 12.10.FC6(以及ClientSDK 4.10.FC6和SQLCMD 90.01进行测试 - 与Microsoft的johnny-come-lately同名无关)。