在Firebird 3.0中使用存储功能或存储过程返回表

问题描述

我正在尝试编写一个存储过程/函数,该存储过程/函数将向我返回一个包含一行或多行数据的表。

返回的数据取决于以下sql语句中显示的变量:

import SwiftUI

struct MyGroup {
    var name:String,items:[String]
}

struct ContentView: View {
    var groups : [MyGroup] = [
        .init(name: "Animals",items: ["?","?","?"]),.init(name: "Vehicles","⛵️"])]
    
    var body: some View {
        NavigationView {
            vstack {
                List {
                    ForEach(groups,id: \.self.name) { group in
                        Section(header: Text(group.name)) {
                            ForEach(group.items,id:\.self) { item in
                                Text(item)
                            }
                        }
                    }
                }
            }.navigationTitle("collections")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

到目前为止,我已经看到有些事情是这样完成的:

  SELECT * FROM table_name AS SD WHERE EXISTS
  (SELECT disTINCT S.PARENT_ID FROM table_name AS S 
  WHERE S.COMPONENT_ID = 10011 AND S.CARRIER_GROUP_ID = X AND SD.SD_ID = S.PARENT_ID)

然后,使用X值调用函数/过程。我知道返回类型有问题,但是我不知道什么。

有人可以帮忙吗?

解决方法

您要寻找的是selectable stored procedure。 Firebird要求您显式声明存储过程返回的列,因此returns table之类的选项不是可选项。例如:

create procedure sp_test_procedure (x integer) 
  returns (column1 integer,column2 varchar(50))
as
begin
  for select value1,value2 
      from table_name SD
      where exists (
        SELECT DISTINCT S.PARENT_ID 
        FROM table_name AS S 
        WHERE S.COMPONENT_ID = 10011 
        AND S.CARRIER_GROUP_ID = X 
        AND SD.SD_ID = S.PARENT_ID)
      into column1,column2
  do
  begin
    suspend;
  end
end

您将需要显式映射列,因此,简单的select *并不是一个好主意。

请注意使用for select(它选择零或更多行并在游标上进行迭代),以及suspend的使用,该输出输出要从存储过程中提取的一行(在本例中为每一行)光标)。

您可以通过此过程产生值,例如:

select column1,column2
from sp_test_procedure(10)