天道酬勤,学无止境

存储过程与无存储过程-安全性观点(Stored Procedures vs No Stored Procedures - Security Viewpoint)

问题

Web应用程序的数据库,从安全的角度看,有什么论据反击的点的SP只有在应用数据库帐户具有表和视图,只有EXEC SP上的任何权利的解决方案?

如果有人拦截了应用程序数据库帐户,则遭受攻击的表面积要比不暴露表和视图时的表面积小得多。 非sp解决方案将提供(或不提供)哪些安全优势? 我看到使用非sp解决方案有很多优点,但是暴露所有表格会使我有些担心。

这个问题是针对一般的主要数据库供应商产品,但具体来说是针对sql server 2008。

回答1

仅从安全角度来看,我看不到非SP方法比SP方法具有的任何优势,因为:

  • 您必须直接授予对基础表等的权限
  • 使用sproc,所有真正的基础架构信息都可以被封装/隐藏(SP也可以被加密)
回答2

假设您公司的会计系统是一个需要真正安全的系统。 如果您使用proc并仅授予对proc的访问权限,则用户将永远无法执行proc之外的任何其他操作。 这是一个内部控件,旨在确保系统的任何用户都不能绕开系统的业务规则。 这就是阻止人们购买公司然后批准资金自己打开欺诈门的原因。 这也可以防止组织中的许多人删除帐户表中的所有记录,因为他们没有删除权限,但从proc授予的权限一次只能删除一个。

现在,开发人员必须拥有更多的权限才能进行开发,但是如果您要考虑安全性的话,他们就不应在生产机器上拥有更多的权限。 的确,开发人员可以写出恶意的sp,在放入产品时会做不好的事情。 但是,同一位开发人员可以将相同的代码放入应用程序版本中,就像他们恶意更改proc一样容易被捕获或无意破坏。 我个人认为proc可能更容易捕获,因为它可能会被dbas与代码分开重新获得,这可能意味着经理或配置管理人员和dbas有机会仅通过经理或配置管理人员来查看它。 我们都知道现实是,没有人推出代码来生产产品,因此没有时间亲自审查每个代码,因此聘请值得信赖的开发人员至关重要。 进行代码审查和源代码控制可以帮助发现恶意更改或将其回滚到以前的版本,但是无论如何,使用SPS副应用程序代码都面临开发人员的风险。

系统管理员也是如此。 必须具有对系统的完整权限才能完成其工作。 他们可能会造成很大的伤害而不会被抓住。 在这种情况下,您可以做的最好的事情就是将访问权限限制为尽可能少的人,并尽最大努力雇用可信赖的人。 至少如果您只有很少的人可以使用此访问权限,那么如果出现问题,则更容易找到问题的根源。 您可以通过进行异地备份来最大程度地降低风险(因此,至少可以解决管理员在备份变坏时所破坏的内容),但是您永远无法完全摆脱这种风险。 同样,无论您以何种方式允许应用程序访问数据,这都是正确的。

因此,sps的真正用途不是消除所有可能的风险,而是使它减少,从而减少危害系统的人员。 从本质上讲,使用应用程序代码来影响数据库信息是不安全的,并且我认为不应在存储财务信息或个人信息的任何系统中使用该代码。

回答3

不使用存储过程的最大安全优势是清晰度。 通过查看其对表的访问权限,您可以确切地知道一个帐户可以做什么。 对于存储过程,不一定是这种情况。 如果一个帐户具有执行过程X的能力,那确实会限制该帐户执行该过程且不会访问基础表,但是X可以执行任何操作。 它可以删除表,更改数据,删除数据等。

要了解帐户可以使用存储过程做什么,您必须查看存储过程。 每次更新存储过程时,都必须有人检查一下它的作用,以确保没有“意外”放置其中。 存储过程中真正的安全性问题来自组织内部,而不是恶意攻击者。

这是一个例子:

假设您正在尝试限制对employee表的访问。 如果没有存储过程,则只需拒绝访问该表。 要获得某人的访问权,必须公然要求您授予权限。 当然,他们可以使您运行脚本来授予访问权限,但是大多数人至少会尝试查看会更改数据库架构的脚本(假设脚本不会更新存储过程,我将在下面进行讨论)。

一个应用程序可能有数百个存储过程。 以我的经验,它们经常更新,请在此处添加一个字段,然后在其中删除一个字段。 对于某人来说,始终要检查更新过程脚本的数量变得令人生畏,在大多数组织中,数据库团队开始仅快速查看该过程(而不是一视同仁),然后继续进行。 这就是真正的问题所在。现在,在此示例中,如果IT员工中的某人想要允许访问表,那么该人只需要滑入一行代码以授予访问权限或执行其他操作即可。 在一个完美的世界中,这会被抓住。 我们大多数人都无法在一个完美的世界中工作。

存储过程的真正问题在于它们给系统增加了某种程度的混淆。 混淆带来了复杂性,而复杂性最终带来了更多的工作来理解管理底层系统。 IT部门中的大多数人都过度劳累,事情逐渐消失。 在这种情况下,您不会尝试攻击系统来获取访问权限,而是使用系统负责人来获取所需的内容。 米特尼克说得对,在安全方面,人是问题。

对组织的多数攻击来自内部。 每当您在任何系统中引入复杂性时,都会出现漏洞,事情可能会被忽略。 不要相信,想想你在哪里工作。 完成有关要求谁访问系统的步骤。 很快您就会意识到,您可以让人们在适当的时候忽略事物。 成功地让参与人员渗透到系统中的关键是要做一些看似无害但确实具有颠覆性的事情。

请记住,如果我要攻击系统:我不是你的朋友;我不是你的朋友。 我对你的孩子或爱好没有兴趣; 我会以任何必要的方式使用您,以获取我想要的东西; 我不在乎我是否背叛了你。 “但是他是我的朋友,所以我相信他相信他的所作所为是正确的,”这个想法在事实之后并不令人感到安慰。

回答4

这是传统知识正确的领域之一:仅公开存储过程就可以更好地控制安全性。 直接访问表和视图比较容易,有时您需要这样做,但是这样做的安全性就会降低。

回答5

好吧,我想您已经真正抓住了问题的核心:如果不对所有CRUD操作使用存储过程,则必须至少为特定于应用程序的数据库用户帐户授予对所有表的至少SELECT权限。

如果要允许数据库帐户执行更多工作,则该帐户可能还需要其他权限,例如能够对某些表进行更新甚至删除。

我看不到非存储proc方法将如何带来任何安全好处-它确实为您打开了大门,但问题确实是:您负担得起吗? 您可以为该应用程序特定的数据库帐户提供足够的安全性,从而不会损害系统的整体安全性吗?

一种可能的折衷办法是使用视图或表访问权限来允许SELECT,但使用存储的proc处理其他所有内容(UPDATE,DELETE,INSERT)-半安全,半方便...

通常,这是便利性(非sp方法;可能使用ORM)和安全性(所有SProc方法;可能更麻烦,但更安全)之间的经典折衷方案。

马克

回答6

除了使用存储过程进行传统的安全隔离(对过程的EXEC权限,依赖于所有权链接进行数据访问)之外,还可以对存储过程进行代码签名,从而对任何服务器功能(如链接服务器,服务器范围管理)进行非常细致和特定的访问控制视图,对存储过程的受控访问,甚至包括用户普通访问之外的其他数据库中的数据。

在T-SQL批处理中发出的普通请求,无论其背后是多么花哨以及多少层代码生成和ORM,都无法对其进行签名,因此无法使用可用的最具体功能强大的访问控制机制之一。

回答7

这是一个不完美的类比,但是我想将数据库的“ dbo”模式中的表与OO术语中的“私有”数据进行比较,并将Views和Stored Procs与“ public”进行比较。 甚至可以将“公共”模式与dbo模式分开,以明确区分。 如果您遵循该想法,那么您将获得安全优势和可扩展性优势。

一个帐户(不是Web应用程序的帐户)具有dbo访问权限并拥有数据库,并且该Web应用程序使用另一个仅限于面向公众的结构的帐户进行连接。

回答8

唯一可能的反对意见是,我遇到了某些语句无法在SP中有效地参数化的情况(并且需要动态sql),这使您有可能在SP中注入SQL。 然而,这实际上是一个非常狭窄的考虑因素,并且是一种罕见的情况。 至少在PostgreSQL中,我偶尔会看到一些必须对此进行额外审查的情况。

总体而言,即使在这些情况下,我认为SP类型的方法在安全性方面也给您带来了好处,因为它们意味着应用程序可以使用通用的反SQL注入机制,而在其他情况下则不可能,并且可以使用您的SP。通过许多应用程序。 此外,如果所有活动都必须通过SP进行,则可以减少对sql注入的暴露,并集中审核问题。

通常,用户做得越少,通常的安全暴露就越少。 这意味着用户使用sql注入攻击的能力越低。

通常,存储过程提供的安全性要比没有过程更好,更细化。

回答9

此处的大多数答案都指定了使用存储过程的安全性优势。 在不忽略这些优点的情况下,有一些未提及的重大缺点:

  • 数据访问模式有时比正在执行的特定过程重要得多。 我们要记录/监视/分析/引发警报/阻止谁访问数据,何时以及如何访问。 使用存储过程时,我们不能总是获得此信息。

  • 一些组织可能有大量的存储过程。 不可能对所有这些进行复查,将重点放在表上可能更有意义(尤其是在考虑到存储过程可能非常复杂,存在错误并引入其他安全性问题时)。

  • 一些组织可能需要分离关注点。 数据库管理员(或任何编写存储过程的人)并不总是安全人员的一部分。 有时,安全人员仅因为他们对业务逻辑不负责,并且编写业务逻辑的人员并不完全受信任,就仅将注意力集中在数据上是必要的。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • LINQ-to-SQL与存储过程? [关闭](LINQ-to-SQL vs stored procedures? [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我看了一下StackOverflow上的“ LINQ入门指南”(LINQ入门指南),但是有一个后续问题: 我们将要启动一个新项目,其中几乎所有数据库操作都将是相当简单的数据检索(该项目的另一部分已经在写数据了)。 到目前为止,我们的大多数其他项目都使用存储过程来处理此类事情。 但是,如果更有意义,我想利用LINQ-to-SQL。 因此,问题是这样的:对于简单的数据检索,LINQ-to-SQL或存储的proc哪种方法更好? 任何特定的赞成或反对? 谢谢。 回答1 LINQ优于sproc的一些优点: 类型安全性:我认为我们都理解这一点。 抽象:对于LINQ-to-Entities尤其如此。 这种抽象还允许框架添加可以轻松利用的其他改进。 PLINQ是向LINQ添加多线程支持的一个示例。 最小的代码更改即可添加此支持。 做这种简单地调用sproc的数据访问代码要困难得多。 调试支持:我可以使用任何.NET调试器来调试查询。 使用sproc,您将无法轻松调试SQL,并且这种经验很大程度上取决于数据库供应商(MS SQL Server提供了查询分析器
  • 什么时候写“ ad hoc sql”比存储过程更好?(When is it better to write “ad hoc sql” vs stored procedures [duplicate])
    问题 这个问题已经在这里有了答案: 将SQL保留在存储过程与代码中的优缺点是什么[关闭] (47个答案) 4年前关闭。 我在整个应用程序中都有100%即席sql。 我的一个伙伴建议我将其转换为存储过程,以提高性能和安全性。 这在我脑海中提出了一个问题,除了速度和安全性之外,还有别的理由继续使用即席sql查询吗? 回答1 SQL Server缓存临时查询的执行计划,因此(在扣除第一次调用所花费的时间上),这两种方法在速度方面将是相同的。 通常,使用存储过程意味着获取应用程序所需的部分代码(T-SQL查询)并将其放在不受源代码控制的位置(可以,但通常不是),并且在其他人不知情的情况下可以更改的地方。 将查询放在这样的中心位置可能是件好事,这取决于有多少不同的应用程序需要访问它们代表的数据。 我通常发现将驻留在应用程序代码本身中的应用程序所使用的查询保持在容易得多。 在1990年代中期,传统观点认为,在性能至关重要的情况下,SQL Server中的存储过程是必经之路,而在当时确实如此。 但是,这种CW背后的原因很长一段时间都没有成立。 更新:此外,在关于存储过程的生存能力的辩论中,经常会在防止proc的过程中调用防止SQL注入的需求。 当然,没有人会认为通过字符串串联来组装即席查询是正确的做法(尽管这只会在串联用户输入时使您遭受SQL注入攻击)。 显然,应该对临时查询进行参数设置
  • MySQL存储过程与复杂查询(MySQL Stored Procedure vs. complex query)
    问题 存储过程的执行情况如何? 是否值得使用它们而不是在PHP / MySQL调用中实现复杂的查询? 回答1 存储过程将使您的性能有所提高,但是大多数情况下,它们是用于执行用简单查询很难或不可能完成的任务。 存储过程非常适合简化许多不同类型的客户端对数据的访问。 数据库管理员之所以喜欢它们,是因为他们控制数据库的使用方式,而不是将这些细节留给开发人员。 寻找索引和适当的表设计以获得更好的性能。 回答2 讨厌,我讨厌有人阅读这些答案并得到错误的印象。 在“ MySQL”上的“ Stored Whatever”实现与“ SQL Server / Oracle”之间确实存在一些非常重要的区别。 参见:http://www.joinfu.com/2010/05/mysql-stored-procedures-aint-all-that/ 每个问这个问题的人都对MySQL的存储过程实现有所了解。 他们错误地认为存储过程已编译并存储在全局存储过程缓存中,类似于Microsoft SQL Server [1]或Oracle [2]中的存储过程缓存。 这是错误的。 完全不正确。 事实是这样:与MySQL服务器的每个连接均维护其自己的存储过程缓存。 花一点时间阅读本文的其余部分和评论。 简短,您将对问题有更好的了解。 回答3 正如在约翰·福克斯(JohnFX)先前的回答中向我指出的那样:
  • 说服顽固的DBA将ORM用于大多数CRUD与存储过程,视图和函数(Convincing a die hard DBA to use an ORM for the majority of CRUD vs Stored Procedures, View, and Functions)
    问题 我已经使用NHibernate,LINQ to SQL和Entity Framework已有一段时间了。 尽管我看到了使用ORM使开发工作快速进行,代码简单以及对象关系阻抗不匹配最小的好处,但我仍然很难说服顽固的SQL dba ORM的优势。 从我的角度来看,ORM至少可用于您所有数据访问的90-95%,而那些真正繁琐的事情需要在适当的过程或函数中完成。 我绝不是说我们必须在ORM中做所有事情的家伙! 问题:有什么更好的论据可以说服一个老式的dba,那就是使用ORM并不是程序员曾经设想过的绝对最糟糕的主意! 回答1 向他们解释,为应用程序执行的每个操作创建存储过程在多个级别上都是不可维护的。 如果架构更改,则很难跟踪所有受影响的存储过程。 确保不会创建多个存储过程来做同一件事是不可能的,或者如果对现有存储过程稍加改动将产生严重的后果是不可能的。 部署后,很难确保应用程序和数据库同步。 动态SQL具有所有这些问题,甚至更多。 回答2 如果要说服他,首先您需要了解使用ORM的问题。 如果您不能解决他所遇到的问题,那么给您一份一般性福利清单将无济于事。 但是,我对他的问题的第一个猜测是,它会阻止他进行任何优化,因为您直接访问表,因此他没有可在其后面工作的抽象层,因此,如果表需要更改或(去)规范化,则他不破坏您的应用程序就无法做到。 如果您想知道为什么DBA会有这种感觉
  • 临时查询与存储过程与动态SQL(Ad hoc queries vs stored procedures vs Dynamic SQL [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 即席查询与存储过程与动态SQL。 谁能说优缺点? 回答1 存储过程 专业:适用于简短查询(又名OLTP,即添加,更新,删除,查看记录) 优点:将数据库逻辑与业务逻辑分开专业版:易于排除故障优点:易于维护优点:通过网络传输的位数更少(即仅过程名称和参数) 专业版:已在数据库中编译优点:更高的安全性(用户不需要直接表访问) 优点:出色的查询计划缓存(适用于OLTP查询-计划重用带来的好处) 缺点:出色的查询计划缓存(不适用于OLAP查询-独特计划带来的好处) 缺点:使您与该SQL供应商联系在一起 动态SQL (即在存储过程中使用exec命令) 优点:适合短而简单的查询(又名OLTP) 优点:将数据库逻辑与业务逻辑分开优点:通过网络传输的位数更少(即仅过程名称和参数) Pro:允许引用任何表,数据库或列 Pro:允许基于参数添加或删除谓词(在WHERE子句中) 优点:良好的查询计划缓存(对于OLTP和OLAP查询而言,性能中等) 缺点:只能编译proc的静态元素缺点:使您与该SQL供应商联系在一起缺点:更难解决缺点:更容易受到SQL注入攻击
  • 什么时候应该使用存储过程?(When should I use stored procedures?)
    问题 什么时候应该使用存储过程,而不是直接在应用程序中直接编写逻辑? 我想获得存储过程的好处,但是我也不想让我的应用程序逻辑散布在数据库和应用程序上。 您是否可以参考任何经验法则? 回答1 哇...我将直接在这里逆流而行,说:“几乎总是”。 有很多原因的清单-我敢肯定其中一些理由会引起争论。 但是我已经开发了带有或不带有存储过程作为数据访问层的应用程序,根据我的经验,编写良好的存储过程使编写应用程序变得如此容易。 然后是有据可查的性能和安全优势。 回答2 这完全取决于您的环境。 问题的答案实际上不是编码问题,甚至不是分析问题,而是业务决策。 如果您的数据库仅支持一个应用程序,并且与之合理地紧密集成,那么出于灵活性的考虑,最好将逻辑放在应用程序中。 在这种情况下,使用通用功能将数据库简单地作为纯数据存储库来处理,就不会给您带来多少损失,也不会带来灵活性-包括供应商,实施,部署和许多其他方面-而且“数据库是针对数据”人群提出的许多纯粹论据都具有示范性真的。 另一方面,如果您正在处理公司数据库,通常可以通过在其中包含多个访问路径来识别它,那么强烈建议您尽可能降低安全性。 至少应该启用所有适当的约束,并且如果可能的话,只能通过视图和过程来访问数据。 在这些情况下,抱怨的程序员应该被忽略,因为... 使用公司数据库,资产是宝贵的,无效的数据或操作可能会威胁到业务。 您最关心的是保护业务
  • 包含有关存储过程参数信息的SQL Server系统表是什么?(What is the SQL Server system table that contains information about stored procedure parameters?)
    问题 包含有关存储过程参数的信息以及诸如数据类型,名称,长度,是否为null的信息的SQL Server系统表是什么? 谢谢 回答1 您可以查询sys.procedures和sys.parameters ... select pr.name, p.* from sys.procedures pr inner join sys.parameters p on pr.object_id = p.object_id 并加入类型... select pr.name, p.*, t.name, t.max_length from sys.procedures pr inner join sys.parameters p on pr.object_id = p.object_id inner join sys.types t on p.system_type_id = t.system_type_id 回答2 您也可以使用 select * from INFORMATION_SCHEMA.PARAMETERS 回答3 您也可以使用 select * from INFORMATION_SCHEMA.ROUTINES \G; 回答4 SELECT p.name AS [SP Name], qs.execution_count, ISNULL(qs.execution_count/DATEDIFF
  • MySQL的存储过程或PHP代码?(MySQL stored procedures or php code?)
    问题 一个一般的问题,没有特定的情况-与使用编写执行相同计算和查询的PHP脚本相比,通常首选使用MySQL存储过程吗? 每种方法的好处是什么? 回答1 Jeff Atwoods的观点/对策观点“反正谁需要存储过程?” 从2004年开始: 1)存储过程以大型铁数据库“语言”(如PL / SQL(Oracle)或T-SQL(Microsoft))编写。 这些所谓的语言是古老的,充满了疯狂,不连贯的设计选择,这些选择总是源于十年向后兼容性的曲折发展。 您真的不想在其中编写很多代码。 就上下文而言,JavaScript是PL / SQL或T-SQL的巨大进步。 响应:“ SQL”中的“ S”表示“结构化”,而不是“标准化”-PLSQL和TSQL都是SQL的自定义扩展,这也使ANSI SQL发挥了作用,因为很少有与数据库无关的SQL。 通常,如果您希望查询执行良好,则不能依赖ANSI SQL。 ORM不是灵丹妙药-由于数据库是抽象的,因此大多数支持运行本机存储过程/函数以获取性能良好的查询。 很好,但完全违背了ORM的目的... 我永远也不会理解为什么Web开发,无数技术(HTML,Javascript / AJAX,Flash等)总是将SQL视为家族的败类。 像其他所有人一样,您必须学习它才能从中获得一些收益。 当使用其他技术时,一定是您获得的即时满足感。 2
  • SQL Server在存储过程中默默地截断varchar(SQL Server silently truncates varchar's in stored procedures)
    问题 根据这个论坛的讨论,SQL Server(我使用的是2005,但我收集到的信息也适用于2000和2008),即使您直接使用插入该字符串,也将其作为存储过程参数指定的任何varchar截短为varchar的长度。 INSERT实际上会导致错误。 例如。 如果我创建此表: CREATE TABLE testTable( [testStringField] [nvarchar](5) NOT NULL ) 然后当我执行以下命令时: INSERT INTO testTable(testStringField) VALUES(N'string which is too long') 我收到一个错误: String or binary data would be truncated. The statement has been terminated. 伟大的。 数据完整性得以保留,并且调用方对此有所了解。 现在,让我们定义一个存储过程以插入该存储过程: CREATE PROCEDURE spTestTableInsert @testStringField [nvarchar](5) AS INSERT INTO testTable(testStringField) VALUES(@testStringField) GO 并执行它: EXEC spTestTableInsert
  • 存储过程,函数和例程之间有什么区别?(What's the differences between stored procedures, functions and routines?)
    问题 在MySQL数据库上下文中,这三个术语之间有什么区别: 存储过程存储功能存储的例程 像那些日期时间函数(例如WEEKDAY()等)这样的内置函数也被认为是什么? 回答1 Google是您的朋友。 “ mysql例程功能过程”的第一个匹配项是:http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html 快速总结: 存储的例程可以是过程,也可以是函数。 使用CALL语句调用过程,并且只能使用输出变量传回值。 可以像其他任何函数一样从语句内部调用一个函数,并且可以返回标量值。 回答2 在这里,我试图总结功能和过程之间的差异: FUNCTION始终使用return语句返回一个值。 PROCEDURE可能通过参数返回一个或多个值,或者根本不返回任何值。 函数通常用于计算,而过程通常用于执行业务逻辑。 函数仅返回1个值。 过程可以返回多个值(最大1024)。 默认情况下,存储过程始终返回零的整数值。 而函数返回类型可以是标量或表或表值。 存储过程有一个预编译的执行计划,而函数则没有。 可以通过SQL语句(例如SELECT func_name FROM DUAL直接调用SELECT func_name FROM DUAL而过程则不能。 存储过程具有安全性并减少了网络流量
  • 实体框架VS LINQ to SQL VS ADO.NET具有存储过程吗? [关闭](Entity Framework VS LINQ to SQL VS ADO.NET with stored procedures? [closed])
    问题 关闭。 此问题不符合堆栈溢出准则。 它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为Stack Overflow的主题。 2年前关闭。 改善这个问题 您如何按照以下方式对每个人进行评分: 表现发展速度整洁,直观,可维护的代码灵活性全面的 我喜欢我的SQL,因此一直是ADO.NET和存储过程的忠实拥护者,但是最近我对Linq to SQL玩了些,对我写DataAccess层的速度感到震惊,并决定花费有一段时间真正了解Linq to SQL或EF ...还是都不了解? 我只想检查一下,这些技术中没有哪一个大缺陷会使我的研究时间变得毫无用处。 例如,性能太差了,它对于简单的应用程序来说很酷,但只能带您走远。 更新:您是否可以专注于EF VS L2S VS SP而不是ORM VS SP。 我主要对EF VS L2S感兴趣。 但是我也很想将它们与存储的proc进行比较,因为我很了解纯SQl。 回答1 首先,如果您要开始一个新项目,请使用Entity Framework(“ EF”)-它现在生成的SQL更好(更像Linq to SQL一样),并且比Linq to SQL更易于维护和更强大(“ L2S”)。 从.NET 4.0版本开始,我认为Linq to SQL是一种过时的技术。 MS对于不再继续进行L2S开发一直持开放态度。 1)表现 这很难回答。 对于大多数单实体操作
  • 代码优先迁移和存储过程(Code First Migrations and Stored Procedures)
    问题 我刚刚创建了一个数据库并完成了第一次迁移(只是添加了一个简单的表)。 现在,我想通过编写sql并在Management Studio中执行它来添加刚刚添加的一些存储过程。 但是我想在迁移中尽可能包含这些存储过程,以便保存它们,并可以对它们运行Up或Down方法。 这可能吗?如果可以,需要使用什么语法? 还是只需要使用Management Studio添加/编辑/删除它们? 回答1 我是这样做的... 在当前的迁移类中- public partial class MyMigration : DbMigration { public override void Up() { ... other table creation logic // This command executes the SQL you have written // to create the stored procedures Sql(InstallScript); // or, to alter stored procedures Sql(AlterScript); } public override void Down() { ... other table removal logic // This command executes the SQL you have written // to
  • 函数与存储过程(Functions vs Stored Procedures)
    问题 假设我必须实现一段T-SQL代码,该代码必须返回一个表作为结果。 我可以实现表值函数,也可以实现返回一组行的存储过程。 我应该使用什么? 简而言之,我想知道的是: 函数和存储过程之间的主要区别是什么? 使用一种或另一种时,我必须考虑哪些因素? 回答1 如果您可能希望将这段代码的结果与其他表合并,那么显然,表值函数将使您可以在单个SELECT语句中组合结果。 通常,有一个层次结构(查看<电视功能<存储过程)。 您可以在每一个中做更多的事情,但是随着功能的增加,组合输出的能力以及使优化器真正参与其中的能力也会降低。 因此,只要使用最少的一种,即可表达您想要的结果。 回答2 函数必须是确定性的,不能用于对数据库进行更改,而存储过程则允许您进行插入和更新等操作。 您应该限制对函数的使用,因为它们会给大型,复杂的查询带来巨大的可伸缩性问题。 它们成为查询优化器的“黑匣子”,您将看到使用函数和将代码简单地插入查询之间的巨大性能差异。 但是,在非常特殊的情况下,它们对于表值收益绝对有用。 如果需要解析以逗号分隔的列表,以模拟将数组传递给过程,则函数可以为您将列表变成表。 这是Sql Server 2005的常见做法,因为我们尚无法将表传递给存储过程(2008年才可以)。 回答3 从文档中: 如果存储过程满足以下条件,则它很可能被重写为表值函数: 该逻辑可以在单个SELECT语句中表示
  • 调试存储过程(以及编写易于调试的sproc)的最佳方法是什么?(What is the best way to debug stored procedures (and write sprocs that are easier to debug)?)
    问题 有什么好的方法可以创建可减轻调试麻烦的存储过程? 还有哪些工具可用于调试存储过程? 也许最重要的是,有什么迹象可以表明错误是在存储过程中发生的,而不是在代码中发生的? 我希望我在这方面不会太糟糕了。 投票解决以上任何一个问题。 谢谢。 对于它的价值,我在.NET环境中工作,即SQL服务器。 回答1 我在存储过程中使用的一种技术可以使它们更易于调试(没有IDE或调试器)以用于SQL Server 2005过程: 我在该过程的参数列表的末尾添加了一个名为@Debug = 0(默认为0 = off)的输入参数。 然后添加(@Debug = 1)print'...'; 关键时刻的代码中的语句,以显示任何有用的内部值等。 是的,这是“老派”,而调试器使您“遍历代码”很棒-但这适用于使用任何SQL工具的任何人(包括使用相同IDE进行调试的任何人)。 罗恩 回答2 我用于简单日志输出和调试的另一种技术是在过程顶部创建一个表变量: --************************************************************************** -- Create a log table variable to store messages to be returned to the -- calling application. --*********
  • SQL存储过程中的动态排序(Dynamic Sorting within SQL Stored Procedures)
    问题 我过去花了数小时研究这个问题。 在我看来,现代RDBMS解决方案应该解决该问题,但是到目前为止,我还没有发现任何能够真正解决我认为在任何具有数据库后端的Web或Windows应用程序中非常普遍的需求的东西。 我说的是动态排序。 在我的幻想世界中,它应该像下面这样简单: ORDER BY @sortCol1, @sortCol2 这是新手SQL和存储过程开发人员在整个Internet论坛上给出的规范示例。 “为什么这不可能?” 他们问。 总是会有人最终向他们讲授存储过程的编译性质,一般的执行计划以及无法将参数直接放入ORDER BY子句的各种其他原因。 我知道你们中有些人已经在想:“那么,让客户来进行分类。” 自然,这会减轻数据库的工作量。 但是在我们的案例中,我们的数据库服务器甚至在99%的时间内都不会汗流breaking背,它们甚至还不是多核的,也不是每6个月进行一次其他任何体系结构的无数改进。 仅出于这个原因,让我们的数据库处理排序就不会有问题。 此外,数据库非常擅长排序。 他们为此进行了优化,并且已经花了好几年的时间来实现它,其实现语言极其灵活,直观,简单,最重要的是,任何SQL初学者都知道该怎么做,更重要的是,他们知道如何对其进行编辑,进行更改,进行维护等。当您的数据库需要负担很多费用而您只想简化(并缩短!)开发时间时,这似乎是一个显而易见的选择。 然后是网络问题。
  • 存储过程真的可以提高MS SQL / .NET的性能吗?(Do Stored Procedures really boost performance in MS SQL / .NET?)
    问题 杰夫·阿特伍德(Jeff Atwood)在这里写到了这一点,尽管我了解存储过程可以提供的理论上的性能提升,但这似乎是一个巨大的痛苦。 使用存储过程,哪种类型的查询会带来最大的性能提升,而您宁愿即时构建哪种类型的查询? 任何文档以一种或另一种方式将不胜感激。 回答1 存储的过程/没有存储的过程参数已成为一个宗教问题。 对于每个强调proc的优化执行计划的人,另一位指出大多数现代DBMS中都对常见的动态查询进行了缓存和优化。 对于指出proc可能提供的安全性的任何人,另一个人解释说,可以进行动态查询一样安全。 有些人喜欢在不重新编译应用程序的情况下更改proc的灵活性,而另一些人则认为查询应在应用程序代码中捕获,以便它们在同一代码库中生存和增长。 我说... 你喜欢什么。 我怀疑我们能否提出正确的答案。 如果proc很麻烦,请不要使用它们。 如果他们似乎是个好主意,那就去吧。 我曾经使用过两种模型,老实说我没有偏爱。 无论有没有他们,我都富有成效。 回答2 在过去的日子里,使用存储过程可带来可观的性能优势,但是查询计划的重用现在明显更好,因此在很多情况下两者几乎是相同的。 如果要在服务器上构建动态SQL,则可以通过使用sp_ExecuteSQL(而不仅仅是EXEC)来执行SQL,从而进一步提高查询计划的重用性(和注入安全性)。 使用存储过程有一些优点:
  • SQL Server性能:更快的存储过程或视图是什么?(SQL-Server Performance: What is faster, a stored procedure or a view?)
    问题 在SQL Server 2005/2008,存储过程或视图中,最快的是什么? 编辑:正如你们中许多人指出的那样,我太含糊了。 让我尝试更具体一些。 我想知道View中特定查询的性能差异,以及存储过程中完全相同的查询的性能差异。 (我仍然感谢所有指出其不同功能的答案) 回答1 正如本文中多次提到的,存储过程(SP)和SQL视图是不同的“野兽”。 如果我们排除一些与查询计划的缓存相关的[除了边缘情况之外,通常是次要的]性能注意事项,与绑定到存储过程相关的时间等,那么这两种方法在性能上总体上是等效的。 然而... 视图被限制为可以在单个SELECT语句中表示的任何内容(当然,可能使用CTE和其他一些技巧),但是通常,视图与声明性查询形式相关。 另一方面,存储过程可以使用各种过程类型的构造(以及声明性的构造),因此,使用SP可以手工制造一种解决给定查询的方法,该方法可能比SQL Server的效率更高。查询优化器可能已完成(基于单个声明性查询)。 在这些情况下,SP可能要快得多(但请注意...优化器非常聪明,并且使SP慢于等效视图并不需要花很多时间。) 除了这些性能方面的考虑外,SP还具有更多用途,并且比视图具有更大范围的查询和操作。 回答2 不幸的是,它们不是同一类型的野兽。 存储过程是一组T-SQL语句,并且CAN可以返回数据。 它可以执行各种逻辑,并且不一定要在结果集中返回数据
  • 如果使用存储过程,我是否可以不受SQL注入的影响?(Am I immune to SQL injections if I use stored procedures?)
    问题 让我们在MySQL数据库上说(如果有关系的话)。 回答1 不,您将不会完全安全。 正如其他人提到的那样,无论您如何访问数据库,参数化查询始终是解决之道。 procs可以确保您的安全,这是一个城市传说。 我认为人们之所以会陷入这种幻想,是因为大多数人都认为您将使用代码中的参数化查询来调用proc。 但是,如果不这样做,例如,如果您执行以下操作,则表示您是敞开的: SqlCommand cmd = new SqlCommand("exec @myProc " + paramValue, con); cmd.ExecuteNonQuery(); 因为您使用的是来自最终用户的未经过滤的内容。 再一次,他们所要做的就是终止行(“;”),添加危险命令,然后动臂-您已经精疲力尽了。 (顺便说一句,如果您在网络上,请不要从浏览器的查询字符串中提取未经过滤的垃圾,这使对数据进行极其糟糕的事情变得异常容易。) 如果您将查询参数化,则状态会好得多。 但是,正如这里其他人提到的那样,如果您的proc仍在生成动态SQL并执行该动态SQL,则可能仍然存在问题。 我应该注意,我不是反进程。 过程对于解决数据访问中的某些问题可能非常有帮助。 但是proc并不是SQL注入的“解决方案”。 回答2 如果您始终使用参数化查询,那么您就不会受到SQL注入的影响。 如果在各处都使用适当的转义
  • 数据库原理——事务、视图、存储过程
    一、事务 概念:事务指的是满足ACID特性的一组操作,可以通过commit提交一个事务,也使用rollback进行回滚。一个或一组语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。 事务的ACID属性: 原子性(Atomicity): 原子性是指事务是一个不可分割的工作单位,事务中的操作要么发生,要么都不发生。一致性(Consistency):事务必须使数据库从一个一致性状态变换到另一个一致性状态。隔离性(Isolation):事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。 事务的创建: 隐式事务:事务没有明显的开启和结束的标记。如insert,update,delete语句。显式事务:事务具有明显的开启和结束的标记。 前提:必须设置自动提交功能为禁用。 set autocommit=0 开启事务 set autocommit=0; start transaction; # 可选的 编写事务中的sql语句(select insert update delete) 语句1; 语句2; ... 设置回滚点; savepoint
  • 什么是存储过程?(What is a stored procedure?)
    问题 什么是“存储过程” ,它们如何工作? 存储过程的组成(每个事物必须是存储过程)是什么? 回答1 存储过程是可以以几种方式执行的一批SQL语句。 大多数主要的DBM支持存储过程。 但是,并非全部。 您将需要使用特定的DBMS帮助文档进行验证以获取详细信息。 因为我对SQL Server最熟悉,所以将其用作示例。 要创建存储过程,语法非常简单: CREATE PROCEDURE <owner>.<procedure name> <Param> <datatype> AS <Body> 因此,例如: CREATE PROCEDURE Users_GetUserInfo @login nvarchar(30)=null AS SELECT * from [Users] WHERE ISNULL(@login,login)=login 存储过程的一个好处是,您可以将数据访问逻辑集中到一个位置,以便DBA轻松优化。 存储过程还具有安全优势,因为您可以授予存储过程执行权限,但是用户将不需要对基础表具有读/写权限。 这是反对SQL注入的良好的第一步。 存储过程确实有缺点,基本上是与基本CRUD操作相关的维护。 假设每个表都有一个Insert,Update,Delete和至少一个基于主键的选择,这意味着每个表将具有4个过程。 现在,建立一个有400个表的体面大小的数据库,您就有1600个过程!