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