2016-12-05 60 views
0

简易版的DDL的执行SQL函数:它应该是可以在DB2 z内的检查约束/ OS

create function rm00dv1.no_concurrent_schedules() 
returns integer 
LANGUAGE SQL 
READS SQL DATA 
NO EXTERNAL ACTION 
NOT DETERMINISTIC 
BEGIN 
    declare num_overlaps integer; 

    select count(*) 
    into num_overlaps 
    from 
     rm00dv1.schedules a 
    where 
     a.id != 0 
     and 
     exists (
      select 1 
      from rm00dv1.schedules b 
      where 
       b.id = 0 -- matches the key of a given record 
       and rm00dv1.isConcurrent(b.schdl_eff_dt, b.schdl_trm_dt, a.schdl_eff_dt, a.schdl_trm_dt) != 0 
     ); 

    return num_overlaps;  
end; 

表:

create table rm00dv1.schedules (
    id int not null, 
    schdl_eff_dt date not null, 
    schdl_trm_dt date not null, 
    info_chg_ts timestamp(6) not null with default 
    ) 
in RM00DV1.TSRMDV01 ; 


alter table rm00dv1.schedules add constraint no_schedule_overlap 
check ((schdl_trm_dt < '01/01/2015') 
     or 
     rm00dv1.no_concurrent_schedules() <= 0); 

我得到了SQL00551N - no execution privilege和很奇怪,因为我可以在select语句中执行该函数。

任何想法来解决这个问题? 谢谢。

回答

1

看起来你不能。我在寻找the DB2 10 for z/OS reference for ALTER TABLE参考,它说下面的检查条件:“A 检查条件是一个搜索条件,具有以下限制:...不能包含... ...内建的,在或用户定义的功能...“。

由于您的函数看起来不会转换为检查条件,因此在表上定义触发器可能是下一个最佳选择。

+1

织补。我阅读了该文档,但错过了这个子弹。谢谢。仅供参考,当我存入内置函数min(1,0)时,出现错误消息,检查约束无效。因此,无论WLM的权限如何,这种方法都无法工作。 –

+0

仅供参考,由于插入或更新操作的有效性取决于表中的值,并且无法访问表,因此触发器本身不起作用。我遇到了这个问题,http://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/codes/src/tpc/n746.html –

+0

@ChrisGolledge请问您是如何解决问题的? – David

0

我知道AFTER触发器没有像BEFORE触发器那样得到-746。我真的想要使用CONSTRAINT,因为最好的方法是捕捉我后面的人的意图,用BEFORE触发器终止活动计划。但是,它看起来像一系列的触发器将成为未来之路。它有点笨重,因为触发器都必须单独创建,你必须一起看看它们以获取意图,并且正确的行为取决于它们的创建顺序。是的,它被记录下来,他们将按照他们的创作顺序执行。行

快乐路径终止没有指定终止日期:

CREATE TRIGGER terminate_no_trm 
after 
INSERT ON schedules 
referencing new as new 
FOR EACH ROW 
MODE DB2SQL 
BEGIN ATOMIC 
update schedules 
set 
    schdl_trm_dt = max(schdl_eff_dt, new.schdl_eff_dt - 1 days) -- prob not necessary, but don't set the trm before the eff 
    , info_chg_ts = new.info_chg_ts 
where 
    new.keyCombo = keyCombo 
    and 
    schdl_trm_dt = '9999-12-31' 
    and schdl_eff_dt < new.schdl_eff_dt; 

end 

防止插入如果插入导致了重叠:

CREATE TRIGGER no_overlapping_schedules_i 
after 
insert ON schedules 
referencing new as n 
FOR EACH ROW 
MODE DB2SQL 

when (num_concurrent_schedules(n.keyCombo) > 0) 
begin atomic 
SIGNAL SQLSTATE '75001' (
    'Concurrent schedules detected: ' 

    concat ' ' concat cast(n.keyCombo as varchar(32)) 
    concat ': ' concat cast(n.schdl_eff_dt as varchar(32)) 
    concat ' to ' concat cast(n.schdl_trm_dt as varchar(32)) 
    ); 
end 

和防止UPDATE如果将导致重叠

CREATE TRIGGER no_overlapping_schedules_u 
after 
update ON schedules 
referencing new as n 
FOR EACH ROW 
MODE DB2SQL 

when (num_concurrent_schedules(n.keyCombo) > 0) 
begin atomic 
SIGNAL SQLSTATE '75001' (
    'Concurrent schedules detected: ' 
    concat ' ' concat cast(n.keyCombo as varchar(32)) 
    concat ': ' concat cast(n.schdl_eff_dt as varchar(32)) 
    concat ' to ' concat cast(n.schdl_trm_dt as varchar(32)) 
    ); 
end 

感谢您的想法。