将SQL保存在c#源代码或Stored Procs中有哪些优点/缺点?我一直在和一个朋友讨论这个问题,我们正在做一个开源项目(c# ASP。网论坛)。目前,大多数数据库访问都是通过在c#中构建内联SQL并调用SQL Server DB来完成的。所以我在试着确定,对于这个特定的项目,哪个是最好的。
到目前为止,我有:
in Code的优点:
更容易维护-不需要运行SQL脚本来更新查询 更容易移植到另一个DB -没有pros到移植
存储Procs的优点:
性能 安全
将SQL保存在c#源代码或Stored Procs中有哪些优点/缺点?我一直在和一个朋友讨论这个问题,我们正在做一个开源项目(c# ASP。网论坛)。目前,大多数数据库访问都是通过在c#中构建内联SQL并调用SQL Server DB来完成的。所以我在试着确定,对于这个特定的项目,哪个是最好的。
到目前为止,我有:
in Code的优点:
更容易维护-不需要运行SQL脚本来更新查询 更容易移植到另一个DB -没有pros到移植
存储Procs的优点:
性能 安全
当前回答
@Terrapin - scprocs同样容易受到注射攻击。正如我所说:
总是参数化所有的查询-永远不要内联用户输入的东西,你会没事的。
这适用于sprocs和动态Sql。
我不确定不重新编译你的应用程序是一个优势。我的意思是,在重新上线之前,您已经针对该代码(应用程序和DB)运行了单元测试。
@Guy -是的,你是对的,sproc确实让你控制应用程序用户,这样他们就只能执行sproc,而不是底层的操作。
我的问题是:如果所有人都通过你的应用程序访问它,使用连接和用户只有有限的更新/插入权限等,这个额外的级别是否增加了安全性或额外的管理?
我的观点是后者。如果他们已经破坏了您的应用程序,可以重新编写它,那么他们还有很多其他的攻击可以使用。
如果动态内联代码,Sql注入仍然可以针对这些spprocs执行,所以黄金法则仍然适用,所有用户输入必须始终参数化。
其他回答
@Terrapin - scprocs同样容易受到注射攻击。正如我所说:
总是参数化所有的查询-永远不要内联用户输入的东西,你会没事的。
这适用于sprocs和动态Sql。
我不确定不重新编译你的应用程序是一个优势。我的意思是,在重新上线之前,您已经针对该代码(应用程序和DB)运行了单元测试。
@Guy -是的,你是对的,sproc确实让你控制应用程序用户,这样他们就只能执行sproc,而不是底层的操作。
我的问题是:如果所有人都通过你的应用程序访问它,使用连接和用户只有有限的更新/插入权限等,这个额外的级别是否增加了安全性或额外的管理?
我的观点是后者。如果他们已经破坏了您的应用程序,可以重新编写它,那么他们还有很多其他的攻击可以使用。
如果动态内联代码,Sql注入仍然可以针对这些spprocs执行,所以黄金法则仍然适用,所有用户输入必须始终参数化。
I'm firmly on the side of stored procs assuming you don't cheat and use dynamic SQL in the stored proc. First, using stored procs allows the dba to set permissions at the stored proc level and not the table level. This is critical not only to combating SQL injection attacts but towards preventing insiders from directly accessing the database and changing things. This is a way to help prevent fraud. No database that contains personal information (SSNs, Credit card numbers, etc) or that in anyway creates financial transactions should ever be accessed except through strored procedures. If you use any other method you are leaving your database wide open for individuals in the company to create fake financial transactions or steal data that can be used for identity theft.
存储的proc也比从应用程序发送的SQL更容易维护和性能调优。它们还允许dba查看数据库结构更改对数据访问方式的影响。我从未遇到过允许动态访问数据库的优秀dba。
@Keith
安全?为什么scprocs会更安全?
正如Komradekatz所建议的,您可以禁止访问表(对于连接到DB的用户名/密码组合),而只允许SP访问。这样,如果有人获得了数据库的用户名和密码,他们可以执行SP,但不能访问表或数据库的任何其他部分。
(当然,执行scproc可以给他们所有他们需要的数据,但这将取决于可用的scproc。给他们访问表的权限,他们就能访问所有东西。)
我更喜欢把它们保存在代码中(使用ORM,而不是内联或特别),这样它们就可以被源代码控制覆盖,而不必保存.sql文件。
此外,存储过程本身并不更安全。使用sproc可以像使用内联一样轻松地编写糟糕的查询。参数化内联查询与sproc一样安全。
我非常支持代码而不是SPROC。第一个原因是保持代码紧密耦合,第二个原因是源代码控制的便利性,而不需要大量自定义实用程序。
在我们的DAL中,如果我们有非常复杂的SQL语句,我们通常将它们作为资源文件,并在需要时更新它们(这也可以是一个单独的程序集,并在每个db中交换,等等……)
这使得我们的代码和sql调用存储在同一个版本控制中,而不会“忘记”运行一些外部应用程序进行更新。