SQLiteException«创建触发器时“ON”附近的逻辑错误

时间:2014-04-12 23:00:42

标签: sql sqlite nhibernate

我试图使用SQLite来运行NHibernate集成测试。 NHibernate' SchemaExport将根据我的映射文件为我设置数据库。这个工作正常,除了我的触发器。这是.hbm文件中的这种触发器的样子:

<database-object>
  <create>
    CREATE TRIGGER TR_PersonInserted ON Person AFTER INSERT AS
    BEGIN
      SET NOCOUNT ON

      UPDATE Person 
      SET    ModifiedDate = GetDate(), CreatedDate = GetDate() 
      FROM   inserted 
      WHERE  Person.PersonId = inserted.PersonId

      SET NOCOUNT OFF
    END
  </create>
  <drop>
  </drop>
</database-object>

这在SQL Server 2012中非常有用。

如果没有此触发器,SchemaExport在使用SQLite时也能正常工作。 使用此触发器,我在创建架构时遇到异常:

  

System.Data.SQLite.SQLiteException:SQL逻辑错误或缺少数据库附近&#34; ON&#34;:语法错误

这不是很具描述性。我已经尝试了几件事情,包括:

  • 删除内容(即BEGINEND之间的所有内容)
  • 删除AS声明
  • 删除ON声明
  • 从触发器名称中删除下划线
  • 在声明
  • 之前添加;

似乎没有任何帮助。

我错过了什么? SQLite中触发器的正确​​语法是什么?

我更喜欢在SQL-Server-2012中也能正常使用的解决方案,但我并不感兴趣,因为如果需要,我可以为每个数据库方言创建不同的触发器。

PS。我正在使用NuGet包System.Data.SQLite (x86/x64)

1 个答案:

答案 0 :(得分:1)

SQLite's CREATE TRIGGER中接受

形式的语法
CREATE TRIGGER t AFTER INSERT ON x
BEGIN {stmts} END

SQL Server's CREATE TRIGGER和提供的架构采用

形式
CREATE TRIGGER t ON x AFTER INSERT
AS {stmts}

使用直接指定的SQL DDL规范化不同数据库引擎中的两种不同语法形式似乎并不实际,特别是考虑到其他差异,例如SQLite中缺少SET NOCOUNT。

根据您的具体情况将其放入一个完整的示例中,这将归结为:

CREATE TRIGGER TR_PersonInserted INSERT ON Person
BEGIN
  UPDATE Person 
  SET    ModifiedDate = DATETIME('NOW'), CreatedDate = DATETIME('NOW')
  WHERE  PersonId = new.PersonId;
END