0

尽管有 Oracle 方面的经验,但我对 DB2 还是很陌生。我无法解决这个问题。我需要在父表中查找丢失的子记录。父表、子表和 join_key 都作为输入参数传递。

我已经在一个程序中尝试过这个能够实现这一点,但是管理员希望它在一个函数中,以便他们可以在选择语句中使用它并以表格格式获取结果。由于父表、子表和 join_key 作为输入参数,我无法将它们作为动态 sql 运行。

create or replace function missing_child_rec(PARENT_TBL VARCHAR(255),JOIN_KEY VARCHAR(255),CHILD_TBL VARCHAR(255))
RETURNS TABLE(Key VARCHAR(255))
LANGUAGE SQL
BEGIN
DECLARE V_SQL VARCHAR(500);
DECLARE C_SQL CURSOR WITH RETURN FOR S_SQL;
SET V_PARENT_TAB = PARENT_TBL;
SET V_KEY = JOIN_KEY;
SET V_CHILD_TAB = CHILD_TBL;
SET V_SQL = 'SELECT DISTINCT '|| JOIN_KEY  || ' FROM ' || V_CHILD_TAB || ' A WHERE NOT EXISTS 
(SELECT ' ||V_KEY || '  FROM ' || V_PARENT_TAB || ' B WHERE A.'||JOIN_KEY || '= B.'||JOIN_KEY ||' )' ;

PREPARE S_SQL FROM V_SQL;
OPEN C_SQL;
CLOSE C_SQL;


RETURN
END

当我尝试编译它时,它说准备是无效的,我什至尝试过立即执行,但这也给出了错误。你能帮我解决如何在 UDF 中使用动态 sql 或解决这个问题的替代逻辑吗

4

1 回答 1

0

解决这个问题的方法不止一种,这里有一种方法。

如果您已经有一个返回正确结果集的有效存储过程,那么您可以从流水线表函数中调用该存储过程。这个想法是流水线表函数可以使用结果集并将其通过管道传递给调用者。

这将适用于 Db2-LUW v10.1 或更高版本,只要数据库未在多个节点上进行分区。它可以在 Db2-for-i v7.1 或更高版本上运行。它不适用于当前版本的 Db2 for Z/os。

假设您的存储过程是sp_missing_child_rec并且它采用与您在问题中显示的函数相同的输入参数,并假设连接列的数据类型是 varchar(100)。

流水线包装表函数看起来像这样:

--#SET TERMINATOR @

create or replace function missing_child_rec(PARENT_TBL VARCHAR(255),JOIN_KEY VARCHAR(255),CHILD_TBL VARCHAR(255))
returns table ( join_column_value varchar(100))
begin
  declare v_rs result_set_locator varying;
  declare v_row      varchar(100); -- to match the join_column_datatype, adjust as necessary
  declare sqlstate char(5) default '00000';
  CALL sp_missing_child_rec( parent_tbl, join_key, child_tbl);
  associate result set locator (v_rs) with procedure sp_missing_child_rec ;
  allocate v_rscur cursor for result set v_rs;
  fetch from v_rscur into v_row;
  while ( sqlstate = '00000') do
      pipe(v_row);
      fetch from v_rscur into v_row;
  end while;
  return;
end@



select * from table(missing_child_rec( 'parent_table' , 'join_column', 'child_table'))
@
于 2019-08-22T17:36:24.247 回答