2016-12-05 1 views
0

Einfache Version des DDL ausführen:Sollte es möglich sein, eine SQL-Funktion in einer Check-Einschränkung innerhalb von 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; 

Tabelle:

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); 

Ich bin ein SQL00551N - no execution privilege bekommen und dass ist seltsam, weil ich die Funktion in einer Select-Anweisung ausführen kann.

Irgendeine Idee, um dieses Problem zu lösen? Danke.

Antwort

1

Sieht aus wie Sie nicht können. Ich schaue the DB2 10 for z/OS reference for ALTER TABLE Referenz und es sagt Folgendes unter CHECK (Check-Bedingung): "A Check-Bedingung ist eine Suchbedingung, mit den folgenden Einschränkungen: ... darf nicht enthalten ... Built- in oder benutzerdefinierten Funktionen ... ".

Da Ihre Funktion so aussieht, als ob sie nicht in eine Überprüfungsbedingung konvertiert wird, könnte die Definition von Triggern auf der Tabelle die nächstbeste Option sein.

+1

Darn. Ich habe diesen Doc gelesen, aber die Kugel verpasst. Vielen Dank. FYI, wenn ich eine eingebaute Funktion, min (1,0) stub-in, bekomme ich eine Fehlermeldung, die Sinn macht, Check Constraint ist ungültig. Unabhängig von den Berechtigungen für WLM funktioniert dieser Ansatz nicht. –

+0

FYI, ein Trigger selbst wird nicht funktionieren, weil die Gültigkeit der Einfüge- oder Aktualisierungsoperation von bereits in der Tabelle vorhandenen Werten abhängt und Sie nicht auf die Tabelle zugreifen können. Ich stieß darauf, http://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/codes/src/tpc/n746.html –

+0

@ChrisGolledge Darf ich fragen, wie Sie das Problem gelöst haben? – David

0

Ich habe gelernt, dass AFTER Trigger keine -746 wie BEFORE Trigger tun. Ich wollte wirklich einen CONSTRAINT verwenden, weil das die Absicht für Leute, die hinter mir her sind, am besten erfasst, mit einem BEFORE-Auslöser, um die aktiven Zeitpläne zu beenden. Aber es sieht so aus, als wäre eine Sequenz von Triggern der richtige Weg. Es ist ein bisschen klobig, weil die Auslöser alle separat erstellt werden müssen und Sie müssen sie zusammen betrachten, um die Absicht zu erhalten, und weil korrektes Verhalten von ihrer Erzeugungsreihenfolge abhängig ist. Ja, es ist dokumentiert, dass sie in der Reihenfolge ihrer Erstellung ausgeführt werden.

glückliche Pfad Beendigung der Zeilen ohne Angabe eines Beendigungsdatum:

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 

Prevent Einsatz der Reihen, wenn die Einlage eine Überlappung verursacht:

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 

und UPDATE verhindern, wenn diese in einer überlappenden Folge hätte

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 

Danke für die Ideen.

Verwandte Themen