繁体   English   中英

使用SqlCommand的最佳实践

[英]Best practices for using SqlCommand

我想确保在使用SqlCommand时,我正在使用最佳实践,尤其是在安全性方面。

我不确定的注意事项:

  1. 可以通过追加来手动构建字符串吗? 如果没有,我该怎么办?
  2. 我应该使用什么类代替?

如果您的第一个问题是谈论通过直接包含值来构建SQL,那几乎肯定不是一件好事。 它使您容易遭受SQL注入攻击以及转换问题(例如,必须获取正确的日期/时间格式)。

相反,您应该使用参数化查询 ,并在参数中设置值。 有关示例,请参见SqlCommand.Parameters的文档。

出于兴趣,您是否有直接使用SQL而不是使用众多ORM之一的特殊原因? (LLBL,实体框架,NHibernate,LINQ to SQL,SubSonic,Massive,SimpleData,Dapper ...)

我会说参数的使用是安全性最重要的方面之一。 这样可以防止将SQL注入到数据库中。 下面的SQLCommand是我将如何构造一个示例(在VB.NET中,抱歉,尚不具备C#知识;);)

Dim cmd as New SqlCommand("sp_StoredProcedure", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery

内联SqlCommand的示例:

Dim cmd as New SqlCommand("SELECT Name, Message FROM [Table] WHERE ID=@ID", Conn)
cmd.commandType = commandtypes.storedprocedure
cmd.parameters.add("@ID",sqldbtype.int).value = myID
cmd.executenonquery

我的建议:懒惰。 编写大量代码是犯人脑致命错误(错误的数据类型,空检查,缺少的Dispose()等)的好方法,并且与许多辅助工具相比,它的性能优势为零

就个人而言,我是小巧的狂热爱好者(但我有些偏见),这使事情变得容易:

int customerId = ...
var orders = connection.Query<Order>(
    @"select * from Customers where CustomerId = @customerId",
    new { customerId });

它将为您轻松完成参数化和实现,而不会带来痛苦。

对于其他情况,尤其是当您想使用OO技术来更新系统时,诸如EF或L2S之类的ORM将节省您的工作时间(并通过LINQ为您提供更好的类型检查)。

我认为这是最好的解决方案

    SqlConnection cn = new SqlConnection(strCn);
        try
        {
            using (SqlCommand cmd = new SqlCommand("select * from xxxx", cn))
            {
                cn.Open();

                //do something

                cn.Close();
            }
        }
        catch (Exception exception)
        {
            cn.Close();
            throw exception;
        }

取决于,当我进行POC或个人小型项目时,我通常会手动构建字符串,但是当我在一个正在工作的项目中时,我们有一个数据库使用和连接模板,我必须使用该模板,而此处显然无法透露。

但是我认为手动构建小型项目或POC中的基本操作是可以的。

  • 编辑:像乔恩所说,尽管在构建自己的命令时应始终使用类似SqlCommand.Parameters的方式。 对不起,如果我不清楚。

如果您担心安全性,建议您在SQL Server数据库内部将查询创建为存储过程(以防止担心SQL注入),然后从前端代码中生成一个SQL存储过程,添加参数,然后那样做

这个文章应该帮助您与设置此功能。

您应该始终使用通过存储过程与数据库进行通信的方式,将最小特权应用于数据库连接。

商店程序

using System.Data;
using System.Data.SqlClient;
using (SqlConnection connection = new SqlConnection(connectionString))
{
  DataSet userDataset = new DataSet();
  SqlDataAdapter myCommand = new SqlDataAdapter("LoginStoredProcedure", connection);
  myCommand.SelectCommand.CommandType = CommandType.StoredProcedure;
  myCommand.SelectCommand.Parameters.Add("@au_id", SqlDbType.VarChar, 11);
  myCommand.SelectCommand.Parameters["@au_id"].Value = SSN.Text;
  myCommand.Fill(userDataset);
}
  • 数据库连接字符串的凭据:A.公司/内联网的集成安全性B.在注册表或主机提供程序中的文件中对其进行加密。

  • 始终注意黑客试图将跨脚本上传到您的表单中。

  • 始终检查输入以进行SQL注入。

暂无
暂无

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

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