简体   繁体   English

将SqlCommand与C#变量一起使用

[英]Using SqlCommand with C# Variables

This is probably a somewhat remedial question, but I'm currently looking to update our database with content from an XML file created in and run through Visual Studio, and I'm fairly certain of what my mistake is, but not how to correct it. 这可能是一个补救性的问题,但是我目前正在寻找使用在Visual Studio中创建并通过Visual Studio运行的XML文件中的内容来更新数据库的方法,我可以肯定我的错误是什么,但不能确定如何纠正它。 Working with Fields field0-field12, this is what I have for each of them. 使用Fields field0-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

Below, I call the SqlConnection and SqlCommand thusly. 在下面,我因此调用SqlConnectionSqlCommand

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();

I'm sure my mistake is in trying to use variables declared in Visual Studio in the Values field of that SQL statement, but I'm not quite sure of what the best workaround for that would be. 我确定我的错误是试图使用在Visual Studio中该SQL语句的“值”字段中声明的变量,但是我不确定哪种最佳解决方法是什么。 Additionally, when it comes time to call SqlCommand upd , I'm not sure I'm doing that properly with upd.ExecuteNonQuery(); 另外,当需要调用SqlCommand upd ,我不确定是否可以使用upd.ExecuteNonQuery();正确地执行此操作upd.ExecuteNonQuery(); .

I hope I'm clear on what I'm asking for with this. 我希望我对此有个明确的要求。 If not, please let me know. 如果没有,请告诉我。 Any kind of assistance would be greatly appreciated. 任何帮助将不胜感激。

You need a parameterized query like this 您需要像这样的参数化查询

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();
}

I stopped to add parameters to the collection just after two examples, but you need to add the other parameters for every parameter placeholder present in the query. 我仅在两个示例之后就停止向集合中添加参数,但是您需要为查询中存在的每个参数占位符添加其他参数。 (The @xxxx ) and most important; @xxxx ),最重要的是; you need to specify the exact data type expected by the underlying table. 您需要指定基础表期望的确切数据类型。

For example, the StartDate field is probably a datetime field and thus its parameter should be defined to be of SqlDbType.DateTime , something like this 例如, StartDate字段可能是日期时间字段,因此应将其参数定义为SqlDbType.DateTime ,类似这样

cmd.Parameters.Add(new SqlParameter
{ 
     ParameterName = "@start", 
     SqlDbType=SqlDbType.DateTime, 
     Value = Convert.ToDateTime(strField11)
});

Notice that for parameters of type NVarChar is important to define the max size of the string passed. 请注意,对于类型为NVarChar的参数,定义传递的字符串的最大大小很重要。 This allows the query optimizer of sqlserver to store the execution plan and reuse it if you call it again with the same parameter sizes. 这允许sqlserver的查询优化器存储执行计划,并在您再次使用相同的参数大小对其进行调用时重新使用它。 This is an interesting article about it. 这是一篇有趣的文章

You have to conver it to paramters liek that 你必须将其转换为参数

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

You can't use the C# variables in a string literal, they won't be detected and interpreted as a column because you have not wrapped them in apostrophes like: 'strField1' . 您不能在字符串文字中使用C#变量,因为它们尚未像'strField1'这样'strField1'引号引起来,所以它们不会被检测并解释为列。 However, you should use sql-parameters anyway, most important because it prevents sql-injection. 但是,无论如何,您都应该使用sql-parameters,这很重要,因为它可以防止sql-injection。

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();

Use the correct types, so for example instead of passing always strings pass a DateTime for a datetime column and a bool to a bit column(that's why i've used boolField ). 使用正确的类型,所以例如强似总是字符串传递DateTimedatetime列和boolbit列(这就是为什么我用boolField )。 If you need to convert them you can use the appropriate methods, for example int.Parse or DateTime.Parse . 如果需要转换它们,则可以使用适当的方法,例如int.ParseDateTime.Parse

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM