5

我的目标是编写一个存储过程,它可以将多行中的所有字段值收集到一个输出变量中(可能是 varchar(some_length))。这可能看起来很奇怪,但我非常肯定它是我在这种情况下唯一可以使用的解决方案。我以前没有使用过 Firebird,并且存储的过程看起来与其他知名数据库系统不同。我的 Firebird 是 1.5 和方言 3(不确定是什么意思)。所以也许有人可以帮助我提供一个算法示例。

4

3 回答 3

5

以下过程按照您的描述进行:

SET TERM !!;
CREATE PROCEDURE concat_names
  RETURNS (concat VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(100);
BEGIN
  concat = '';
  FOR SELECT first_name || ' ' || last_name FROM employee INTO :name
  DO BEGIN
    concat = concat || name || ', ';
  END
END!!
SET TERM ;!!
EXECUTE PROCEDURE concat_names;

但我质疑这种解决方案的智慧。你怎么知道 VARCHAR 对你想要的数据集中的所有行来说足够长?

运行查询以将结果逐行返回到应用程序要容易得多且安全得多。每种应用程序编程语言都有连接字符串的方法,但更重要的是它们有更灵活的方法来管理数据的增长。

顺便说一下,Firebird 和 InterBase 中的“方言”是指引入的一种兼容模式,以便为 InterBase 5.x 开发的应用程序可以与更高版本的 InterBase 和 Firebird 一起使用。那是差不多十年前的事了,AFAIK 今天不需要使用低于方言 3 的任何东西。

于 2008-10-08T18:24:38.907 回答
0

连接时必须测试空值,这是两个字段和它们之间的分隔符的示例:

    CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385),
    F2 VARCHAR(385),
    SEPARATOR VARCHAR(10))
RETURNS (
    RESULT VARCHAR(780))
AS
begin

  if ((:f1 is not null) and (:f1 <> '')) then
    result = :f1;

  if ((:f2 is not null) and (:f2 <> '')) then
    if ((result is not null) and (result <> '')) then
      begin
        if ((:separator is not null) and (separator <> '')) then
          result = result||separator||f2;
        else
          result = result||f2;
      end
    else
      result = f2;

  suspend;
end
于 2008-10-09T04:18:24.840 回答
0

使用 Firebird 存储过程返回多行非常简单。

不要使用:

execute procedure proc_name(value);

而是使用:

select * from proc_name(value);
于 2012-08-31T02:28:13.723 回答