Domanda

Ho un paio di trigger in un database Sybase ASE che viene sparato su aggiornamenti a due tabelle: docs e trans.

I trigger sono definiti come mostrato qui:

Per i documenti:

 CREATE TRIGGER dbo.Index_Change_Docs
 ON dbo.docs
 FOR INSERT,UPDATE AS

 IF UPDATE(DOCTYPE) OR UPDATE(BATCH_NO) OR UPDATE(SCANDATE) OR           
 UPDATE(PERIOD_START_DATE) OR UPDATE(PERIOD_END_DATE) 
 OR UPDATE(DISPATCH_ID) OR UPDATE(DISPATCH_NAME) OR UPDATE(CHECKNUM) OR    
 UPDATE(CHECKAMT)
 BEGIN
    INSERT INTO 
    DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE) 
    SELECT Inserted.DOCID, GETDATE(), "N" FROM Inserted

 END

Per trans:

 CREATE TRIGGER dbo.Index_Change_Trans
 ON dbo.Trans
 FOR INSERT,UPDATE AS

 IF UPDATE(TRANSNUM) OR UPDATE(CONTRACT) OR UPDATE(FRANCHISE) OR UPDATE(SSN) OR      
 UPDATE(STATE_CODE) OR UPDATE(TRANSTYPE)
OR UPDATE(AGENCYNUM) OR UPDATE(LOCKBOXBATCHNUM) OR UPDATE(PRODUCTCODE) 
 BEGIN

    INSERT INTO 
    DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
    SELECT DOCID, GETDATE(), "N" FROM DOCS
    WHERE Transnum = (SELECT Inserted.TransNum from Inserted)
 END

Sembra che il comportamento di questi trigger sia diverso, a seconda di come vengono effettuati gli aggiornamenti a quelle tabelle.

In un caso, queste tabelle vengono aggiornate tramite due procedure memorizzate (insert_docs_sp e insert_trans_sp). Quando ciò accade, ogni trigger viene sparato una volta (una volta per i documenti, uno per trans) e tutto funziona come previsto.

In un altro caso, queste tabelle vengono aggiornate all'interno di una transazione Sybase con due aggiornamenti del database. Qui, il primo aggiornamento viene eseguito tramite in linea SQL nell'applicazione chiamante (che spara il trigger trans.) Il secondo aggiornamento viene eseguito tramite una procedura memorizzata - Insert_docs_sp, lo stesso dell'altro caso - che non spara un trigger.

Forse c'è qualcosa su come vengono gestite le transazioni che non capisco?

È stato utile?

Soluzione 2

Ho trovato la risposta: è nell'ordine di esecuzione. Pensavo che uno dei trigger non fosse stato licenziato - in questo caso il trigger index_change_trans - ma in realtà lo era. Non ho visto i risultati, tuttavia, perché questo grilletto si basa sulle voci nella tabella dei documenti.

INSERT INTO 
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT DOCID, GETDATE(), "N" FROM DOCS
WHERE Transnum = (SELECT Inserted.TransNum from Inserted)

Quindi, nei casi in cui la tabella trans è stata aggiornata prima della tabella Docs, l'esecuzione del trigger trans non mostrerebbe un aggiornamento nella tabella Docid_Sync - poiché a questo punto non c'erano voci nella tabella Docs con il valore transnum appropriato. In questi casi, la tabella DOCID_SYNC ha solo una voce, il risultato del trigger DOCS.

In altri casi, la tabella Docs viene aggiornata per prima e quindi la tabella trans. In questi casi, la tabella Docid_Sync ha due voci: una come risultato del trigger Docs e un'altra come risultato del trigger trans.

Altri suggerimenti

In entrambi i trigger, il trigger viene inserito solo nella tabella docid_sync se alcune colonne vengono aggiornate. Sei sicuro che la procedura memorizzata stia aggiornando una delle colonne nel trigger? Anche i trigger non sono chiamati se si tratta di un aggiornamento ricorsivo da una chiamata di innesco, ma non sembra essere il caso qui.

L'altra possibilità è se la transazione chiamante disabilita il trigger con il comando Imposta. Inizierei a garantire che la procedura memorizzata stia aggiornando una delle colonne nei controlli del trigger.

Un'altra domanda: la stessa riga viene aggiornata due volte, nella procedura SQL e memorizzata in linea nel caso di errore o stanno aggiornando due righe diverse?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top