Firebird 2.1存储过程连接多行上的文本

时间:2010-11-25 16:35:26

标签: stored-procedures concatenation firebird firebird2.1

我正在尝试编写一个存储过程来连接多行文本以将其作为单个字符串返回。例如:

CREATE TABLE TEST (
 ID INTEGER,
 SEQ INTEGER,
 TEXT VARCHAR(255));

COMMIT;

INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 1, "LINE 1");
INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 2, "LINE 2");
INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 3, "LINE 3");

COMMIT;

SET TERM !!;
CREATE PROCEDURE concat_names (iID INTEGER)
  RETURNS (CONCAT VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(255);
BEGIN
  CONCAT = '';
  FOR SELECT TEXT FROM TEST where id=:iID INTO :name
  DO BEGIN
    CONCAT = CONCAT || name;
  END
END!!
SET TERM ;!!

commit;

但是当我跑步时:

select concat from concat_names(1);

它总是返回零行。

有什么想法吗?

3 个答案:

答案 0 :(得分:8)

你忘记了SUSPEND。你的proc应该是这样的:

SET TERM !!;
CREATE PROCEDURE concat_names (iID INTEGER)
  RETURNS (CONCAT VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(255);
BEGIN
  CONCAT = '';
  FOR SELECT TEXT FROM TEST where id=:iID INTO :name
  DO BEGIN
    CONCAT = CONCAT || name;
  END
  SUSPEND;
END!!
SET TERM ;!!

没有存储过程,您可以获得相同的结果。使用LIST聚合函数:

SELECT LIST(text, '') FROM TEST where id=:iID 

LIST的第二个参数是分隔符。如果您仅使用字段名称调用LIST,则将使用逗号','来分隔值。

答案 1 :(得分:0)

如果字段TEST可以为null并且您不希望将整个结果设置为null,则使用它是有用的:

 CONCAT = CONCAT || coalesce(name,'');

而不是

CONCAT = CONCAT || name;

答案 2 :(得分:0)

如果不使用存储过程并使用版本Firebird 2.5, LIST 聚合函数将返回“列中的非空值的逗号分隔字符串连接”*。使用前面提到的TEST表,SQL

SELECT LIST(TEXT)
    FROM TEST

返回

第1行,第2行,第3行

这可能有一些兴趣。

*取自Firebird参考页面here