Note that there are some explanatory texts on larger screens.

plurals
  1. POAre database triggers safe for cross table integrity constraints?
    primarykey
    data
    text
    <p>I suggested using a trigger to check a cross table integrity constraint answering <a href="https://stackoverflow.com/a/16878683/2032064">this question</a>. It has been suggested in the comments that it may cause problems:</p> <blockquote> <p>Triggers to do cross row checks rarely work on most databases ... because they cannot read uncommitted rows from other transactions</p> </blockquote> <p>I haven't found any source supporting the claim, though. <a href="http://docs.oracle.com/cd/B28359_01/appdev.111/b28843/tdddg_triggers.htm#autoId3" rel="nofollow noreferrer">Official</a> <a href="http://dev.mysql.com/doc/mysql-reslimits-excerpt/5.1/en/stored-program-restrictions.html#stored-routines-function-restrictions" rel="nofollow noreferrer">documentation</a> doesn't mention anything. Others issues I found are covered <a href="https://stackoverflow.com/q/460316/2032064">here on SO</a> - it mostly criticizes potential hidden complexity as triggers are not visible on first sight. Bet even the <a href="https://stackoverflow.com/a/460343/2032064">highest rated answer</a> admits their usage for integrity issues.</p> <p>So my question is: <strong>Are database triggers safe for cross table integrity constraints?</strong> Specially, would the solution below work?</p> <hr> <p>To summarize the original question. We have tables</p> <ul> <li>Player - PlayerID, PlayerName</li> <li>Bet - BetID, BetName</li> <li>plays_in - BetID, PlayerID</li> </ul> <p>The constraint it that the combination of BetName and PlayerID sholud be unique. Definition of the suggested trigger:</p> <pre><code>CREATE TRIGGER check_bet_name BEFORE INSERT ON plays_in FOR EACH ROW BEGIN DECLARE bet_exists INT DEFAULT 0; DECLARE msg VARCHAR(255); SELECT 1 INTO bet_exists FROM Bet AS b1 WHERE b1.BetID = NEW.BetID AND EXISTS (SELECT * FROM plays_in AS p JOIN Bet AS b2 USING (BetID) WHERE p.PlayerID = NEW.PlayerID AND b2.BetName = b1.BetName ) LIMIT 1; IF bet_exists THEN SET msg = "Bet name already exists..."; SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; END IF; END// </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload