使用ExecuteSqlCommand()创建触发器在单词' TRIGGER'附近引发"语法错误。'。

时间:2014-10-31 13:07:32

标签: c# entity-framework triggers dbcontext

这似乎我错过了一个简单的细节,我只是无法弄清楚是什么。

有了这个

string deleteTrigger =
            "IF OBJECT_ID('@p0') IS NOT NULL " +
            "DROP TRIGGER [@p1] ";
string createTrigger = 
            "CREATE TRIGGER [@p0] " +
            "ON [dbo].[@p1] " +
            "AFTER DELETE AS " +
            "BEGIN " +
                "SET NoCount ON " +
                "DELETE FROM [dbo].[MyTable] WHERE ID IN (SELECT ID FROM DELETED) " +
            "END ";

object[] parameterList = new object[] {"Tr_SomeTable_AD", "Tr_SomeTable_AD" };
context.Database.ExecuteSqlCommand(deleteTrigger,parameterList); // Works
parameterList = new object[] { "Tr_SomeTable_AD", "SomeTable" };
context.Database.ExecuteSqlCommand(createTrigger, parameterList); // Exception thrown here!
我的InitializeDatabase(DbContext)中的

引发异常:

  

SqlException:单词' TRIGGER'

附近的语法不正确

在第二个ExecuteSqlCommand上(第一个工作正常)。我也试过了

context.Database.ExecuteSqlCommand(createTrigger, "Tr_SomeTable_AD", "SomeTable");

而不是使用object[],但结果是相同的。

我看到了this question,但答案并没有解决我的问题。我知道问题必须与我使用参数这一事实有关,因为如果我只是将值放在createTrigger字符串中,那么SQL命令就可以工作。但是,我希望对其进行参数化,以便更容易在不同的表上使用相同的触发器创建代码。

SOLUTION:

如@marc_s所述(参见下面的答案),我无法在T-SQL中参数化表或列(或触发器)名称 - 我必须在C#中创建完整的最终T-SQL语句(使用的String.format())。因此:

string deleteTrigger = "..."; // same as before
string createTrigger = 
            "CREATE TRIGGER [dbo].[{0}] " + 
            "ON [dbo].[{1}] " + ...

object[] parameterList = new object[] {"Tr_SomeTable_AD", "Tr_SomeTable_AD" };
context.Database.ExecuteSqlCommand(string.Format(deleteTrigger,parameterList)); 
parameterList = new object[] { "Tr_SomeTable_AD", "SomeTable" }; // Use string.Format() here!
context.Database.ExecuteSqlCommand(string.Format(createTrigger, parameterList));

诀窍。

1 个答案:

答案 0 :(得分:0)

无法参数化T-SQL中的表或列(或触发器)名称;遗憾的是,DDL(数据定义语言)语句无法进行参数化。

您必须在C#中创建完整的最终T-SQL语句(使用string.Format()),然后执行完整的T-SQL语句。