【问题标题】:How to a filter on the result on a stored procedure in DB2如何过滤 DB2 中存储过程的结果
【发布时间】:2018-04-19 14:32:54
【问题描述】:

我在 DB2 中有一个存储过程,它返回一堆列。我需要应用“WHERE”条件或对其返回的列之一进行排序。我不想在调用存储过程时触摸存储过程并进行此过滤/排序,如下所示

select * from 'call SP1()' as T where T.column1 > 10

这在 DB2 中可行吗?

【问题讨论】:

  • 只需创建另一个存储过程来进行过滤,这可能是一种更明智且更简单的方法。
  • 考虑使用返回表值的用户定义函数。您可以从表 UDF 中进行选择(使用 SELECT * FROM TABLE(YOUR_UDF()) ),UDF 可以做许多 SP 可以做的事情 ibm.com/support/knowledgecenter/SSEPGG_11.1.0/… 您还可以在 UDF 中调用一个 SP 和 PIPE() 如果您需要从 SP 返回的行 @ 987654322@
  • 您能否在“答案”中给我一个 PIPE() 的示例?
  • 好的。我的第二条语句错了,UDF 可以 PIPE() 输出行,但 UDF 不能从 SP 访问结果集,只能访问 OUT 或 INOUT 参数。很抱歉让您抱有希望。所以 mao 是对的,将你的 SP 包装在另一个 SP 中。否则,将代码从 SP 内部复制出来并将其放入 UDF 中。根据 SP 正在做什么,您可以在一个值为 UDF 的表中执行相同的操作
  • 我上面说的不是真的.. 看下面的答案

标签: db2 db2-luw


【解决方案1】:

这是一个故意人为设计的流水线 UDF 示例,用于过滤 SQLPL 过程的结果集。

在现实世界的编码中,大多数程序员会避免在存储过程之外进行过滤,这仅仅是因为它更容易、性能更好,而且尽早过滤更自然。

在 DB2_COMPATIBILITY_MODE=ORA 的 Db2-LUW v11.1.3.3 和 11.1.2.2 上进行了测试(或在 0x10000 中至少将 Bit-17 设置为 1,感谢 P.Vernon 的澄清):

--#SET TERMINATOR @

create or replace procedure alltabs
dynamic result sets 1
language sql
specific alltabs
begin
  declare v_cur cursor with return to caller for 
      select tabschema,tabname,type  from syscat.tables ;
  open v_cur;
end@


create or replace function allstatviews()
returns table (stat_view_name varchar(80))
begin
  declare v_rs result_set_locator varying;
  declare v_tabschema varchar(128);
  declare v_tabname   varchar(128);
  declare v_type      char(1);
  declare sqlstate char(5) default '00000';
  call alltabs;
  associate result set locator (v_rs) with procedure alltabs;
  allocate v_rscur cursor for result set v_rs;
  fetch from v_rscur into v_tabschema, v_tabname, v_type;
  while ( sqlstate = '00000') do
      if v_type='V' and v_tabschema='SYSSTAT'
      then
          pipe(cast(rtrim(v_tabschema)||'.'||rtrim( v_tabname) as varchar(80)));
      end if;
      fetch from v_rscur into v_tabschema, v_tabname, v_type;
  end while;
  return;
end@

select * from table(allstatviews())
@

【讨论】:

  • 啊。很高兴看到您可以从表 UDF 中 PIPE() 一个 SP 结果集。我有一种感觉这是可能的,但是在检查 KC 时它说它不是:“当在触发器、复合语句、函数或方法中调用过程时:无法访问从过程返回的结果集。”。有时最好尝试一下
  • 实际上,该代码在 11.1.3.3 上对我不起作用。我得到User‬‎ ‪defined‬‎ ‪routine ... ‪attempted‬‎ ‪to‬‎ ‪modify‬‎ ‪data‬‎ ‪but‬‎ ‪was‬‎ ‪not‬‎ ‪defined‬‎ ‪as‬‎ ‪MODIFIES‬‎ ‪SQL‬‎ ‪DATA‬‎...SQLCODE‬‎=‪‬‎-‪577‬‎‪‬‎。如果我添加MODIFIES‬‎ ‪SQL‬‎ ‪DATA‬‎,我会得到Multiple‬‎ ‪or‬‎ ‪conflicting‬‎ ‪keywords‬‎ ‪involving‬‎ ‪the‬‎ ‪‬‎"‪MODIFIES SQL DATA"‬‎ ‪clause‬‎ ‪are‬‎ ‪present‬‎.‪‬‎.‪‬‎ ‪SQLCODE‬‎=‪‬‎-‪628‬‎
  • 对我有用,但仅在 11.1.3.3 上(即在 11.1.2.2 上给出与您相同的症状)。假设您的 fp3 mod3 已提交,请尝试新创建的数据库或针对该数据库成功运行相关的 db2updv111*。如果您的构建级别标识符与我的不同(“0204010F”)
  • 是的,仅适用于 db2set DB2_COMPATIBILITY_VECTOR=ORA 和 db2stop/start。好吧,具体来说,如果需要在该向量上设置第 17 位 db2set DB2_COMPATIBILITY_VECTOR=10000 ibm.com/support/knowledgecenter/SSEPGG_11.1.0/… 这是有道理的,因为这是“例程(存储过程或用户定义的函数)可以执行 SQL 语句的程度”ibm.com/support/knowledgecenter/SSEPGG_11.1.0/… 这解释了为什么手册的其他部分说不允许...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-06
  • 2014-01-24
  • 2019-08-24
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
相关资源
最近更新 更多