2009-06-29 7 views
9

私はsqlite用のトリガを作成しようとしているだけで、あらゆる種類の問題に取り掛かります。実際には、私の本当の問題は、SQL言語の私の貧弱な背景にあると私は思う。とにかくここに行く...SQLiteで条件付きSQLトリガを作成する

私はテーブル1とテーブル2の2つのテーブルを持っています。 Table1にはtimeという名前の列があります(これは64ビットの整数時間です)。私はTable1に挿入されている新しい行を監視するトリガーが必要です。 Table1にXより大きい時間を持つ3つ以上の行がある場合(以下の例では120秒のハードコード値)、Table2に新しい行を挿入する必要があります。ここで

はそこにあらゆる種類の魂が

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 

(これは動作しません注意してください)私がこれまで持っているもの、私よりもSQLで優れている誰ですか?

答えて

8

WHEN句が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; 

は、あなたがこのreference pageを見たことがありますか?私が言うことから、これはおそらくWhenセクションのステートメントに由来する「集約の誤用」です。あなたは、この持っていた:

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> 

私はexpressionにそれを作るために「WHERE tCount」を削除しようとしたが、その後私は、オペレータの構文エラーを得ました。

代わりに、私は上記の解決策について話を変えました。

+0

リンクは機能しません。はい、sqliteのウェブサイトのSQLリファレンスの多くは使用しています。私はちょうどそれを取得していないよ。 –

+0

はい、StackOverflowには自分のリンクに問題があります。http://sqlite.org/lang_createtrigger.html; %5fを '_'に変更してください。 – dlamblin

+0

@チーフス - トリガーWHEN節は、数値を返す代わりに、真または偽を返す比較式を期待していると思います。したがって、2番目のフォーマットが有効です。 exprのSQLite構文図からは、この場合true/falseを返す必要があることは明らかではないので、それはあなたにとって紛らわしいことです。 SQLiteは十分に文書化されていますが、まだギャップがあります。私はSQLiteチームに電子メールを送り、これに言及したいと思います。 –

-5

異なる構文アプローチですか?

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 

また、いくつかのデバッグ文を試してみてください。 Webサービスの最後のトリガをデバッグしていたときに、私が設定したデバッグテーブルにINSERT文を入れました。したがって、トリガが呼び出されるたびに@timeNumを出力してから、別のデバッグINSERTをループの中に入れて、実際にTable2 INSERTロジックに入るかどうかを確認することができます。

更新日: 大変申し訳ございません。 SqlLiteのようなものだと思うが、私はこの構文のいくつかが欠けていることは知らなかった。それでも、答えが得られない場合は、コードパスが適切な条件で呼び出されていることを確認するデバッグステートメントを検討してください。

+1

sqliteでDECLARE、SET、IFを使用することはできません。 – dlamblin

+3

あなたのコードはSQLiteではなくT-SQLです。 SQLiteには、手続き型の言語構造がありません。 –

1

トリガー内のWHEN句は、数値を返す代わりに真または偽を返す比較式でなければなりません。 dlamblinのアイデアを試してみてください。