将SqlCommand与C#变量一起使用

将SqlCommand与C#变量一起使用,c#,sql,visual-studio,C#,Sql,Visual Studio,这可能是一个有点补救性的问题,但我目前正在寻找使用VisualStudio中创建并运行的XML文件中的内容更新我们的数据库,我很确定我的错误是什么,但不知道如何纠正它。使用字段0-field12,这是我为每个字段准备的 string strField0; //strField0 - strField12 var doc = XDocument.Load("serializer.xml"); foreach (var xe in doc.Root.Elements("UserReportPrev

这可能是一个有点补救性的问题,但我目前正在寻找使用VisualStudio中创建并运行的XML文件中的内容更新我们的数据库,我很确定我的错误是什么,但不知道如何纠正它。使用字段0-field12,这是我为每个字段准备的

string strField0; //strField0 - strField12
var doc = XDocument.Load("serializer.xml");

foreach (var xe in doc.Root.Elements("UserReportPreviewListDto"))
{
    XElement field0 = xe.Element("Field0");
    ConvertField(xe, "Field0", TranslateValueField);
    if (field0 != null)
    {
        strField0 = field0.Value;
    }
}
//strField0 - strField12
下面,我调用
SqlConnection
SqlCommand

SqlConnection conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
string update =
    "INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail], [Type], [CustomForeColor], Inactive], [ModifiedDate], [CreatedDate], [ModifiedById], [CreatedById], [StartDate], [EndDate])
    VALUES (strField1, strField2, strField3, strField4, strField5, strField6, strField7, strField8, strField9, strField10, strField11, strField12)";
SqlCommand upd = new SqlCommand(update, conn);
conn.Open();
upd.ExecuteNonQuery();
我确信我的错误在于试图在SQL语句的Values字段中使用VisualStudio中声明的变量,但我不太确定最好的解决方法是什么。此外,当调用
SqlCommand upd
时,我不确定我是否正确地使用
upd.ExecuteNonQuery()


我希望我清楚地知道我对这件事的要求。如果没有,请告诉我。非常感谢您的任何帮助。

您需要这样的参数化查询

string update = @"INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail], 
                  [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                  [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@code, @description, @sendemail, @type, @forecol, @inactive,
                          @moddate, @createdate,@modby, @createby,@start, @end)";

string conString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using(SqlConnection conn = new SqlConnection(conString))
using(SqlCommand cmd = new SqlCommand(update, conn))
{
    conn.Open();
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@code", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=25,  // or whatever size you have for this field in the table 
        Value = strField1
    });
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@description", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=255, // Same as before, the size should be equal to the field length on the table
        Value = strField2
    });
    .... and so on for the other parameters ....
    upd.ExecuteNonQuery();
}
cmd.Parameters.Add(new SqlParameter
{ 
     ParameterName = "@start", 
     SqlDbType=SqlDbType.DateTime, 
     Value = Convert.ToDateTime(strField11)
});
在两个示例之后,我停止向集合添加参数,但是您需要为查询中存在的每个参数占位符添加其他参数。(xxxx)和最重要的;您需要指定基础表所需的确切数据类型

例如,
StartDate
字段可能是一个datetime字段,因此其参数应该定义为
SqlDbType.datetime
,类似于

string update = @"INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail], 
                  [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                  [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@code, @description, @sendemail, @type, @forecol, @inactive,
                          @moddate, @createdate,@modby, @createby,@start, @end)";

string conString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using(SqlConnection conn = new SqlConnection(conString))
using(SqlCommand cmd = new SqlCommand(update, conn))
{
    conn.Open();
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@code", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=25,  // or whatever size you have for this field in the table 
        Value = strField1
    });
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@description", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=255, // Same as before, the size should be equal to the field length on the table
        Value = strField2
    });
    .... and so on for the other parameters ....
    upd.ExecuteNonQuery();
}
cmd.Parameters.Add(new SqlParameter
{ 
     ParameterName = "@start", 
     SqlDbType=SqlDbType.DateTime, 
     Value = Convert.ToDateTime(strField11)
});

请注意,对于NVarChar类型的参数,定义传递的字符串的最大大小非常重要。这允许sqlserver的查询优化器存储执行计划,并在使用相同的参数大小再次调用时重用它。这是一个关于它的问题。

您需要这样一个参数化查询

string update = @"INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail], 
                  [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                  [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@code, @description, @sendemail, @type, @forecol, @inactive,
                          @moddate, @createdate,@modby, @createby,@start, @end)";

string conString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using(SqlConnection conn = new SqlConnection(conString))
using(SqlCommand cmd = new SqlCommand(update, conn))
{
    conn.Open();
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@code", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=25,  // or whatever size you have for this field in the table 
        Value = strField1
    });
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@description", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=255, // Same as before, the size should be equal to the field length on the table
        Value = strField2
    });
    .... and so on for the other parameters ....
    upd.ExecuteNonQuery();
}
cmd.Parameters.Add(new SqlParameter
{ 
     ParameterName = "@start", 
     SqlDbType=SqlDbType.DateTime, 
     Value = Convert.ToDateTime(strField11)
});
在两个示例之后,我停止向集合添加参数,但是您需要为查询中存在的每个参数占位符添加其他参数。(xxxx)和最重要的;您需要指定基础表所需的确切数据类型

例如,
StartDate
字段可能是一个datetime字段,因此其参数应该定义为
SqlDbType.datetime
,类似于

string update = @"INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail], 
                  [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                  [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@code, @description, @sendemail, @type, @forecol, @inactive,
                          @moddate, @createdate,@modby, @createby,@start, @end)";

string conString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
using(SqlConnection conn = new SqlConnection(conString))
using(SqlCommand cmd = new SqlCommand(update, conn))
{
    conn.Open();
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@code", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=25,  // or whatever size you have for this field in the table 
        Value = strField1
    });
    cmd.Parameters.Add(new SqlParameter
    { 
        ParameterName = "@description", 
        SqlDbType=SqlDbType.NVarChar, 
        Size=255, // Same as before, the size should be equal to the field length on the table
        Value = strField2
    });
    .... and so on for the other parameters ....
    upd.ExecuteNonQuery();
}
cmd.Parameters.Add(new SqlParameter
{ 
     ParameterName = "@start", 
     SqlDbType=SqlDbType.DateTime, 
     Value = Convert.ToDateTime(strField11)
});

请注意,对于NVarChar类型的参数,定义传递的字符串的最大大小非常重要。这允许sqlserver的查询优化器存储执行计划,并在使用相同的参数大小再次调用时重用它。这是一个关于它的问题。

你必须把它转换成参数

string update = "INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail]....)
    VALUES (@strField1, @strField2, @strField3, ..";
SqlCommand upd = new SqlCommand(update, conn);
upd.Parameters.AddWithValue("@strField1", "1"); 
   ....

你必须把它交给Parameters liek

string update = "INSERT INTO [dbo].[TABLE] ([Code], [Description], [SendEmail]....)
    VALUES (@strField1, @strField2, @strField3, ..";
SqlCommand upd = new SqlCommand(update, conn);
upd.Parameters.AddWithValue("@strField1", "1"); 
   ....
您不能在字符串文本中使用C变量,它们不会被检测到并解释为列,因为您没有将它们包装在撇号中,如:
“strField1”
。但是,无论如何都应该使用sql参数,最重要的是因为它阻止sql注入

string update = @"INSERT INTO [dbo].[TABLE] (
                    [Code], [Description], [SendEmail], 
                    [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                    [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@Code, @Description, @SendEmail,@Type, @CustomForeColor, @Inactive,
                    @ModifiedDate, @CreatedDate, @ModifiedById, @CreatedById, @StartDate, @EndDate)";
SqlCommand upd = new SqlCommand(update, conn);
upd.Parameters.Add("@Code", SqlDbType.VarChar).Value = strField1;
upd.Parameters.Add("@Description", SqlDbType.VarChar).Value = strField2;
upd.Parameters.Add("@SendEmail", SqlDbType.Bit).Value = boolField;
// and so on ....
conn.Open();
upd.ExecuteNonQuery();
使用正确的类型,例如,不要总是传递字符串,而是为
DateTime
列传递
DateTime
,为
bit
列传递
bool
(这就是为什么我使用
boolField
)。如果您需要转换它们,可以使用适当的方法,例如
int.Parse
DateTime.Parse

您不能在字符串文本中使用C变量,它们不会被检测到并解释为列,因为您没有将它们封装在诸如:
'strField1'
之类的撇号中。但是,无论如何都应该使用sql参数,最重要的是因为它阻止sql注入

string update = @"INSERT INTO [dbo].[TABLE] (
                    [Code], [Description], [SendEmail], 
                    [Type], [CustomForeColor], [Inactive], [ModifiedDate], [CreatedDate], 
                    [ModifiedById], [CreatedById], [StartDate], [EndDate])
                  VALUES (@Code, @Description, @SendEmail,@Type, @CustomForeColor, @Inactive,
                    @ModifiedDate, @CreatedDate, @ModifiedById, @CreatedById, @StartDate, @EndDate)";
SqlCommand upd = new SqlCommand(update, conn);
upd.Parameters.Add("@Code", SqlDbType.VarChar).Value = strField1;
upd.Parameters.Add("@Description", SqlDbType.VarChar).Value = strField2;
upd.Parameters.Add("@SendEmail", SqlDbType.Bit).Value = boolField;
// and so on ....
conn.Open();
upd.ExecuteNonQuery();

使用正确的类型,例如,不要总是传递字符串,而是为
DateTime
列传递
DateTime
,为
bit
列传递
bool
(这就是为什么我使用
boolField
)。如果需要转换它们,可以使用适当的方法,例如
int.Parse
DateTime.Parse

当运行时返回的错误是
System.Data.dll中发生了类型为“System.Data.SqlClient.SqlException”的未处理异常。其他信息:无效列名“strField1”。列名“strField2”无效。
运行时返回的错误是
System.Data.SqlClient.SqlException类型的未处理异常在System.Data.dll中发生。其他信息:列名“strField1”无效。列名“strField2”无效。
感谢您的帮助,Steve。到目前为止,它看起来不错,但是对于每个条目,它都给了我一个错误“使用未分配的局部变量'strFieldX'”,尽管它们的值在上面的XElement语句中分配。有什么想法吗?如果你看一下,错误信息是正确的。仅当
if(field0!=null)
条件为真时,才分配变量strFieldX。因此,如果字段条件为false,则永远不会初始化变量。编译器无法知道该条件运行时的结果,并发出错误消息。可以在声明strFieldX变量时为其指定默认值来解决此问题。IE:
string strField0=string.Empty我遇到了日期字段为空值且无法转换和写入Insert语句的问题。有没有关于解决这个问题的想法?我建议发布一个新问题。通过这种方式,更多的人可以看到你的问题,而不是少数几个还在看这个问题的人,你可以得到更快的答案。如果此答案或此处的其他答案解决了您的原始问题,请选择最适合您的问题的答案。史蒂夫,否则这可能会成为一种不受欢迎的感谢方式。到目前为止,它看起来不错,但是对于每个条目,它都给了我一个错误“使用未分配的局部变量'strFieldX'”,尽管它们的值在上面的XElement语句中分配。有什么想法吗?如果你看一下,错误信息是正确的。仅当
if(field0!=null)
con