首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数化查询

参数化查询
EN

Stack Overflow用户
提问于 2016-07-25 18:17:54
回答 5查看 295关注 0票数 2

我是一个新的VisualC#,我对如何编写参数化查询感到困惑。这是我没有他们的密码,

代码语言:javascript
复制
using System;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Insert_Data
{
    public partial class Form1 : Form
    {
        private void button1_Click(object sender, EventArgs e)
        {
            SqlConnection con = new SqlConnection("Data Source=ZTABASSUM\\SQLEXPRESS01;Initial Catalog=IntroDataBase;Integrated Security=True");
            con.Open();
            SqlCommand sc = new SqlCommand("Insert into employee values ('"+ textBox1.Text +"' , " + textBox2.Text + ", '" + textBox3.Text + "',  " + textBox4.Text + ", " + textBox5.Text + ");", con);
            int o = sc.ExecuteNonQuery();
            MessageBox.Show(o + ":Record has been inserted");
            con.Close();
        }
    }
}

我不确定如何为每个文本框编写参数化查询。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-07-25 19:00:07

我在代码中添加了注释,并在后面添加了一个best practices重述。

代码语言:javascript
复制
// best practice - use meaningful method names
private void buttonSaveEmployee_Click(object sender, EventArgs e)
{
    // best practice - wrap all database connections in a using block so they are always closed & disposed even in the event of an Exception
    // best practice - retrieve the connection string by name from the app.config or web.config (depending on the application type) (note, this requires an assembly reference to System.configuration)
    using(SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString))
    {
        // best practice - use column names in your INSERT statement so you are not dependent on the sql schema column order
        // best practice - always use parameters to avoid sql injection attacks and errors if malformed text is used like including a single quote which is the sql equivalent of escaping or starting a string (varchar/nvarchar)
        // best practice - give your parameters meaningful names just like you do variables in your code
        SqlCommand sc = new SqlCommand("INSERT INTO employee (FirstName, LastName, DateOfBirth /*etc*/) VALUES (@firstName, @lastName, @dateOfBirth /*etc*/)", con);

        // best practice - always specify the database data type of the column you are using
        // best practice - check for valid values in your code and/or use a database constraint, if inserting NULL then use System.DbNull.Value
        sc.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar, 200){Value = string.IsNullOrEmpty(textBoxFirstName.Text) ? (object) System.DBNull.Value : (object) textBoxFirstName.Text});
        sc.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar, 200){Value = string.IsNullOrEmpty(textBoxLastName.Text) ? (object) System.DBNull.Value : (object) textBoxLastName.Text});

        // best practice - always use the correct types when specifying your parameters, in this case a string is converted to a DateTime type before being assigned to the SqlParameter.Value
        // note - this is not a very robust way to parse a date as the user is never notified in the event of failure, the purpose here is simply to show how to use parameters of various types
        DateTime dob;
        sc.Parameters.Add(new SqlParameter("@dateOfBirth", SqlDbType.Date){Value = DateTime.TryParse(textBoxDateOfBirth.Text, out dob) ? (object) dob : (object) System.DBNull.Value});

        // best practice - open your connection as late as possible unless you need to verify that the database connection is valid and wont fail and the proceeding code execution takes a long time (not the case here)
        con.Open();
        int o = sc.ExecuteNonQuery();
        MessageBox.Show(o + ":Record has been inserted");

        // the end of the using block will close and dispose the SqlConnection
        // best practice - end the using block as soon as possible to release the database connection
    }
}

使用ADO.NET的最佳实践概述

  • 将所有数据库连接包装在一个using块中,以便它们总是被关闭&即使在异常情况下也会被释放。有关使用语句的更多信息,请参见使用语句(C#引用)
  • 从app.config或web.config (取决于应用程序类型) 中按名称检索连接字符串

  • 始终将参数用于传入值到
    • 避免sql注入攻击
    • 如果使用格式错误的文本,如包含单引号,则避免错误,因为单引号相当于转义或启动字符串(varchar/nvarchar)。
    • 让数据库提供程序重用查询计划(并非所有数据库提供程序都支持),从而提高效率

  • 当使用参数时
    • 给Sql参数取有意义的名称,就像在代码中使用变量一样。
    • 指定要使用的列的数据库数据类型,这将确保不使用可能导致意外结果的错误参数类型。
    • 在将传入的参数传递给命令之前,要验证它们,有一个名为“垃圾中的垃圾”的表达式。在堆栈中尽早验证传入的值。
    • 在分配参数值时使用正确的类型,例如:不要分配DateTime的字符串值,而是将实际的DateTime实例分配给参数的值。
    • 不要使用AddWithValue方法,主要原因是在需要时很容易忘记指定参数类型或精度/比例尺。有关更多信息,请参见我们可以停止使用AddWithValue了吗?

  • 当使用数据库连接时,
    • 尽可能晚地打开连接并尽快关闭它。这是使用任何外部资源时的一般指导原则。
    • 永远不要共享数据库连接(例如:拥有单个主机、共享数据库连接)。让您的代码始终在需要时创建一个新的数据库连接实例,然后让调用代码处理它,并在完成时将其“丢弃”。原因是
      1. 大多数数据库提供程序都有某种类型的连接池,所以在托管代码中这样做非常便宜。
      2. 如果代码开始处理多个线程,它将消除任何未来的错误。

票数 4
EN

Stack Overflow用户

发布于 2016-07-25 18:23:11

应该在SQL命令对象上使用create参数方法。

将SQL命令中的字符串更改为

"Insert into employee values (@Employee1,@Employee2,@Employee3,@Employee4,@Employee5);"

然后在执行查询之前添加以下参数:

代码语言:javascript
复制
sc.Parameters.AddRange(new[]{

    new SqlParameter("@Employee1",SqlDbType.VarChar,255){ Value= textBox1.Text},
    new SqlParameter("@Employee2",SqlDbType.VarChar,255){ Value= textBox2.Text},
    new SqlParameter("@Employee3",SqlDbType.VarChar,255){ Value= textBox3.Text},
    new SqlParameter("@Employee4",SqlDbType.VarChar,255){ Value= textBox4.Text},
    new SqlParameter("@Employee5",SqlDbType.VarChar,255){ Value= textBox5.Text}

});

注意: --这是假设您的VARCHAR变量的类型为VARCHAR,大小为255,有关所使用的方法和正在使用的SqlParameter构造函数的更多信息,请参阅MSDN以获得更多文档。

票数 2
EN

Stack Overflow用户

发布于 2016-07-25 18:30:09

参数化查询用于避免sql注入。直接包含非参数(数据)的查询称为参数化查询。通过使用它,我们可以避免sql注入(一种类型的黑客攻击)。

c#中的参数化查询示例

代码语言:javascript
复制
    string strQuery;
    SqlCommand cmd;
    strQuery = "insert into customers (CustomerID, CompanyName) values(@CustomerID, @CompanyName)";
    cmd = new SqlCommand(strQuery);
    cmd.Parameters.AddWithValue("@CustomerID", "A234");
    cmd.Parameters.AddWithValue("@CompanyName", "DCB");
String strConnString = system.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString;
        SqlConnection con = new SqlConnection(strConnString);
        cmd.CommandType = CommandType.Text;
        cmd.Connection = con;
        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
            return true;
        }
        catch (Exception ex)
        {
            Response.Write(ex.Message);
            return false;
        }
        finally
        {
            con.Close();
            con.Dispose();
        }

。。

类似地,您也可以使用select查询。

有关参考资料,请参阅此链接

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38574826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档