2009-06-29 5 views
9

Ich versuche, einen Trigger für SQLite zu schreiben und nur in alle Arten von Problemen zu laufen. In Wahrheit denke ich, dass mein Problem mit meinem schlechten Hintergrund in der SQL-Sprache ist. Anyway here goes ...Erstellen eines bedingten SQL-Triggers in SQLite

Ich habe zwei Tabellen Table1 und Table2. Tabelle1 hat eine Spalte namens time (die eine 64-Bit-Integer-Zeit ist). Ich brauche einen Trigger, der darauf achtet, dass eine neue Zeile in Table1 eingefügt wird. Wenn in Tabelle 1 3 oder mehr Zeilen vorhanden sind, deren Zeit größer als X ist (ein fest codierter Wert im folgenden Beispiel 120 Sekunden), muss eine neue Zeile in Tabelle 2 eingefügt werden.

Hier ist, was ich bisher (Anmerkung dies nicht funktioniert)

CREATE TRIGGER testtrigger AFTER 
INSERT ON Table1 WHEN 
( 
    SELECT COUNT() AS tCount FROM 
    ( 
    SELECT * FROM Table1 WHERE 
     time > (NEW.time - 120) 
    ) WHERE tCount > 3 
) 
BEGIN 
    INSERT INTO Table2 (time, data) VALUES 
    (NEW.time, 'data1'); 
END 

Jede Art Seelen gibt, die in SQL besser sind als ich?

Antwort

8

Das funktioniert, weil die WHEN Klausel muss ein expression:

sqlite> .schema Table1 
CREATE TABLE Table1 (time int); 
CREATE TRIGGER testtrigger AFTER INSERT ON Table1 
WHEN 3<(SELECT Count() FROM Table1 WHERE time>(NEW.time-120)) 
BEGIN 
INSERT INTO Table2 (time, data) VALUES (NEW.time,'data1'); 
END; 

Sind Sie in diesem reference page geschaut? Von dem, was ich sagen kann, ist dies ein "Missbrauch von Aggregat", der wahrscheinlich aus der Aussage in der When Abschnitt stammt. Sie hatte dies:

sqlite> .tables 
Table1 Table2 
sqlite> .schema Table1 
CREATE TABLE Table1 (time int); 
CREATE TRIGGER testtrigger AFTER 
INSERT ON Table1 WHEN 
( 
    SELECT COUNT() AS tCount FROM 
    ( 
    SELECT * FROM Table1 WHERE 
     time > (NEW.time - 120) 
    ) WHERE tCount > 3 
) 
BEGIN 
    INSERT INTO Table2 (time, data) VALUES 
    (NEW.time, 'data1'); 
END; 
sqlite> .schema Table2 
CREATE TABLE Table2 (time int,data string); 
sqlite> insert into Table1 VALUES (5); 
SQL error: misuse of aggregate: 
sqlite> 

Ich habe versucht, „WHERE tCount“ Löschen sie in eine expression zu machen, aber dann bekam ich einen Syntaxfehler an den Bediener.

Also stattdessen habe ich Dinge für die obige Lösung geschaltet.

+0

Link funktioniert nicht und ja ich habe viel von der SQL-Sprache Referenz auf SQLite-Website gewesen. Ich bekomme einfach nicht "es". –

+0

Yeah StackOverflow hat ein Problem mit meinem Link, sollte es sein: http://sqlite.org/lang_createtrigger.html; ändere die% 5f in ein '_' – dlamblin

+0

@Typhoid - Ich denke, die Trigger-WHEN-Klausel erwartet einen Vergleichsausdruck, der wahr oder falsch zurückgibt, anstatt eine Zahl zurückzugeben. Also das zweite Format sollte funktionieren. Aus dem SQLite-Syntaxdiagramm für expr geht nicht hervor, dass Sie etwas haben müssen, das in diesem Fall true/false zurückgibt. Daher ist es sinnvoll, dass es für Sie verwirrend ist. SQLite ist gut dokumentiert, hat aber immer noch Lücken. Ich maile dem SQLite-Team und erwähne dies. –

-5

Vielleicht ein anderer syntaktischer Ansatz?

CREATE TRIGGER testtrigger ON Table1 

FOR INSERT 
AS 
BEGIN 

    DECLARE @timeNum int 

    SET @timeNum = SELECT count(*) FROM Table1 WHERE time > (New.time - 120) 

    IF @timeNum > 3 

    BEGIN 
     INSERT INTO Table2 (time, data) VALUES 
      (NEW.time, 'data1'); 
    END 

END 

Aber auch, versuchen Sie einige Debugging-Anweisungen. Als ich meinen letzten Auslöser für einen Webservice debugging, habe ich einige INSERT-Anweisungen in eine Debugging-Tabelle eingefügt, die ich eingerichtet habe. Also könnten Sie @timeNum jedes Mal ausgeben, wenn der Trigger aufgerufen wird, und dann ein weiteres Debug-INSERT in die Schleife einfügen, um zu sehen, ob Sie tatsächlich in Ihre Table2-INSERT-Logik kommen.

UPDATE: Entschuldigung! Sieht so aus, als ob SqlLite irgendwie saugt, ich wusste nicht, dass es etwas von dieser Syntax fehlt. Wenn Sie jedoch keine Antworten erhalten, sollten Sie einige Debugging-Anweisungen in Betracht ziehen, um sicherzustellen, dass Ihre Code-Pfade unter den richtigen Bedingungen aufgerufen werden.

+1

Ich glaube nicht, dass Sie DECLARE, SET oder IF in sqlite verwenden können – dlamblin

+3

Ihr Code ist T-SQL, nicht SQLite. SQLite enthält keine prozeduralen Sprachkonstrukte. –

1

Ihre WHEN-Klausel im Trigger sollte ein Vergleichsausdruck sein, der true oder false zurückgibt, anstatt eine Zahl zurückzugeben. Versuchen Sie dlamblin's Idee.

Verwandte Themen