【问题标题】:What is your best-practice advice on implementing SQL stored procedures (in a C# winforms application)?您对实现 SQL 存储过程(在 C# winforms 应用程序中)的最佳实践建议是什么?
【发布时间】:2010-05-27 07:01:55
【问题描述】:

我已经阅读了这些关于 SQL 存储过程的关于 SO 的非常好的问题:

我是集成 .NET/SQL 的初学者,尽管我在其他环境中使用基本 SQL 功能已有十多年了。现在是在组织和部署方面取得进展的时候了。我正在使用 .NET C# 3.5、Visual Studio 2008 和 SQL Server 2008;尽管这个问题可以被视为与语言和数据库无关,这意味着它可以很容易地应用于使用存储过程和关系数据库的其他环境。

鉴于我有一个包含内联 SQL 查询的应用程序,并且我有兴趣转换为存储过程以用于组织和性能目的,您对此有何建议?

以下是我脑海中与此主题相关的一些其他问题,可能有助于形成答案:

  • 是否应该使用 SQL Management Studio 在 SQL 中创建存储过程,并在为客户端安装数据库时简单地重新创建数据库?
  • 在我的应用程序中,在数据库初始化方法中创建所有存储过程是否会更好?
  • 假设在新安装中创建存储过程必须在创建表之后创建似乎是合乎逻辑的。我的数据库初始化方法创建新表并插入一些默认数据。我的计划是在该步骤之后创建存储过程,但我开始认为可能有更好的方法从头开始设置数据库(例如在程序的安装程序中)。对此的想法表示赞赏。
  • 我在整个应用程序中有各种查询。一些查询非常简单 (SELECT id FROM table),而另一些则非常长且复杂,执行多个连接并接受大约 80 个参数。我应该用存储过程替换所有查询,还是只替换那些可能从中受益的查询?
  • 最后,由于这个主题显然需要一些研究和教育,您能否推荐一篇文章、书籍或教程来介绍使用存储过程而不是直接语句的细微差别?

【问题讨论】:

    标签: sql stored-procedures


    【解决方案1】:

    考虑跳过 ORM 的存储过程。考虑使用:

    • LINQ To SQL
    • Entity Framework
    • SubSonic

    • 当您可以为您的应用程序增加更多价值时,您将编写更少的样板代码 ListCustomerGetCustomerByID

    • IMO,没有任何真正令人信服的理由选择使用我们在 Microsoft 堆栈中拥有的现代工具集的存储过程。

    • 远离内联 SQL 语句很好,ORM 将帮助您参数化查询。你不必考虑它。

    • 您根本不必处理 ADO.NET 对象。以面向对象的方式编写数据访问代码。

    【讨论】:

    • 感谢您的提示,我会阅读这些提示。我从 msdn.microsoft.com/en-us/library/aa697427%28VS.80%29.aspx 的实体框架开始
    • 强烈反对。存储过程可以更轻松地针对复杂查询进行性能调整,它们更易于部署更改,最重要的是,它们允许您通过不允许直接访问表来防止潜在的欺诈。
    • SP 似乎是一个非常两极分化的问题,感谢您的意见。在采用新方法之前,我肯定需要一些时间。
    • @HLGEM:anything 比 ORM 更容易进行性能调整。
    【解决方案2】:

    有几个令人信服的理由可以避免让表访问非常多的登录名,包括应用程序登录名,这些理由推动了存储过程的使用。 (出于性能原因,我通常不认为使用 SP 有任何重要性 - SQL Server 甚至缓存即席查询计划。

    存储过程为您的数据库提供了更多定义其接口边界的能力。在许多情况下,视图不足以控制界面。

    任何仅基于表和视图构建的框架(请注意,许多框架都可以构建在 SP 结果之上)在让您的数据库自我保护和控制方面受到严重限制。

    作为一个简单的例子,表和视图都不能被参数化。如果您有一个非常大的表或视图,并且希望强制所有用户指定一组特定的过滤条件(例如快照日期或生效日期),则无法在数据库调用接口处强制执行此操作。该框架可以随时提交查询。如果表/视图没有公开,并且唯一的接口是通过一个 SP 或表值 UDF,那么该 SP 或 UDF 的参数必须提供,从而满足您的数据库的需要,以确保使用得当。

    视图可能有效也可能无效的其他示例包括隐藏某些用户的隐私信息、隐藏内部密钥、隐藏内部实现细节以及执行复杂的安全规则。

    就创建数据库架构的脚本(包括按正确依赖顺序的对象)而言,有多种工具可以执行此操作(并生成更改脚本),包括 Red Gate SQL Compare 和 Apex SQLScript。

    【讨论】:

    • 另外,您应该编写脚本来创建存储的过程并将它们存储在源代码管理中以供以后部署。
    【解决方案3】:

    如果您确实有性能要求,请使用存储过程,特别是如果一个存储过程每分钟会被调用数千次。这种方式sql引擎避免了处理语句的几个步骤。 GPS跟踪系统就是一个例子。假设您有 10000 辆汽车,每分钟报告 3 个位置。在这种情况下,存储过程有助于提高性能。

    如果没有,请使用 ORM 功能,而不是 CRUD sql 语句。

    【讨论】:

      【解决方案4】:

      你错过了一个:

      When is it better to write "ad hoc sql" vs stored procedures

      我的回答是:根本不要使用存储过程

      【讨论】:

      • 你是对的,这是一个很好的。毕竟,我认为SP不是要走的路。 p.campbell 提出了其他几个我没有考虑过的选项,我正在调查这些选项。谢谢。
      • 从安全的角度来看,任何需要访问数据库的面向公众的服务都不应该直接从表中读取。另一点是使用 SProcs 允许一次重构 DB 而无需更改使用 DB 的接口。
      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-24
      相关资源
      最近更新 更多