【发布时间】:2013-02-14 07:24:23
【问题描述】:
我想使用 SQL UDF 聚合一些行。我想首先选择按其 id 排序的行,然后将它们连接到逗号分隔的列中。我的函数中的 order by 子句有错误,因为它位于 for 循环内。有没有办法在不删除 order by 子句的情况下运行它?我的数据库是 DB2
CREATE FUNCTION mySchema.getDates(recId INTEGER)
RETURNS VARCHAR(1024)
LANGUAGE SQL
BEGIN ATOMIC
DECLARE STR VARCHAR(1024);
SET STR = '' ;
LOOP1 : FOR ROW AS (select replace(char(myDate,EUR),'.','/') as myDate from myTable.BookingDates where recId=recId order by rec_crt-id)
DO
IF ROW.myDate IS NOT NULL THEN
SET STR = STR || CAST ( ROW.myDate AS VARCHAR ( 20 ) ) || ', ' ;
END IF ;
END FOR;
RETURN STR ;
END
SQL State: 42601 Vendor Code: -199 Message: [SQL0199] Keyword ORDER not expected. Valid tokens: ) UNION EXCEPT. Cause . . . . . : The keyword ORDER was not expected here.
【问题讨论】:
-
... 为什么要将它作为分隔列?大多数类型的格式化应该在应用层完成。什么版本的 DB2?此外,SQL 通常不应该与循环一起使用,因为大多数引擎都不是为了在这些术语中“思考”而编写的。而
EUR是一种“模糊”格式,在那个月/日可能会出现反转(尤其是在使用“标准”分隔符时)。如果我看到这个输出,我可能会假设美国格式的日期!请注意,这可以通过使用递归 CTE 来完成,尽管我不确定它应该是...... -
@Clockwork-Muse 感谢您的详细回复,我同意您不使用循环的观点,但这是一个愚蠢的要求。要求是一个报告,我必须显示查询已返回的每一行数据的日期。我使用 EUR 将日期格式化为 dd/MM/yyyy 格式(默认情况下它们以 yyyy/dd/MM 存储在数据库中)。
-
@Clockwork-Muse 关于递归,我不想使用递归,因为它容易出错。我也不知道递归 sql 语句的最大级别。
-
@DamienJoe,递归不会比任何其他方法更容易出错。而且实际上你可以走多远没有限制——它不像递归函数调用将东西放在堆栈上。我刚刚测试了一个 10,000,000 级别的递归查询,它运行良好。如果行数很少,使用循环没有任何问题。但是,如果此解决方案太慢,您可能需要查看递归解决方案。
-
如果
myDate实际上是一个日期/时间戳类型(这是一个可怕 列名),它并不是真正以ISO 格式存储的。如果您已经有行,为什么不能从那里提取日期 - 其余数据如何显示?
标签: sql db2 user-defined-functions