一些观察
存储过程为您提供代码重用和封装(软件开发的两个支柱),
仅当您在应该使用它们的上下文中正确使用它们时。关于功能(在结构化编程中)或方法(在面向对象的编程中),可以说相同的主张,但是,我们看到了1K函数和兆资产对象。
工件不会给您带来这些好处。正确使用这些工件可以带来这些好处。
安全性(您可以授予/撤消对单个存储过程的权限),
是。这是一个好点,也是我喜欢存储过程的主要原因之一。与仅使用视图和用户帐户通常可以实现的访问控制相比,它们提供了更好的粒度访问控制。
保护您免受SQL注入攻击,
这不是特定于SP的,因为您可以通过参数化的SQL语句和输入清理获得相同级别的保护。但是,除了“深度安全性”问题之外,我还将使用SP 。
并且还有助于提高速度(尽管DBA表示,从SQL Server 2008开始,如果常规SQL查询运行了足够的时间,则它们也会被编译)。
这是特定于数据库供应商的,但是总的来说,您的DBA是正确的。确实会编译SQL语句(静态或参数化)。如果您希望/需要聚合和计算您无法使用简单的SQL语句完成的数据,但是与SQL紧密集成并且不保证往返于应用程序服务器,则SP可提供帮助。
一个很好的例子是将数据查询到一个或多个临时游标中,以便从中运行另一个SQL本身。您可以在应用服务器中以编程方式进行操作,也可以通过在数据库中进行操作来保存多次往返。
但是,这不应该成为常态。如果您遇到许多情况,则表明数据库设计不正确(或者您正在跨部门从不太兼容的数据库架构中提取数据)。
我们正在使用敏捷软件开发方法开发复杂的应用程序。
敏捷性与软件工程流程和需求管理有关,而与技术无关。
任何人都可以考虑为什么不想使用存储的proc的充分理由吗?
错误的问题
这个问题是错误的,等同于询问“是否有充分的理由不使用GOTO”?在这个问题上,我与尼克劳斯·沃斯(Niklaus Wirth)的支持远胜于迪克斯特拉(Dijkstra)。我可以理解Dijkstra的情绪来自何处,但我认为这并非在所有情况下均100%适用。与商店进程和任何技术相同。
如果工具可以很好地用于其预期目的,并且是完成特定任务的最佳工具,那么它就是好工具。否则使用它并不表示该工具是错误的,而是表明焊工不知道他/她在做什么。
正确的问题是“应避免使用哪种类型的存储过程使用模式”。或者,“在什么条件下我(或不应)使用存储过程”。寻找不使用技术的原因只是将责任归咎于工具,而不是将工程责任直接归咎于工程师。
换句话说,这是一种无知或无知的声明。
我的猜测是,DBA不想维护那些存储的proc,但是似乎有太多负面因素无法证明这种设计决策是正确的。
然后,他们正在做的事情是将不良的工程决策结果投射到他们使用不足的工具上。
您该怎么办?
我的经验是,在罗马时,就像罗马人一样。
不要打架 如果您公司的员工希望将存储过程贴上标签,这是一种不良做法,请让他们使用。但是请注意,这可能是其工程实践中的一个危险信号。
通常在带有大量无能的程序员的组织中将事物标记为不良实践。通过将某些事物列入黑名单,组织试图限制由于自身能力不足而在内部造成的损害。我不拉你
概括是所有失败的源泉。说存储过程(或任何类型的技术)是不好的做法,这是一种概括。概括是无能的解决方案。工程师不能进行公然的概括。他们会根据具体情况进行分析,权衡分析并根据手头的事实执行工程决策和解决方案,以解决问题。
好的工程师不会以这种笼统的方式将事情标记为不良实践。他们着眼于问题,选择合适的工具,进行权衡。换句话说,他们从事工程。
我对如何不使用它们的看法
不要在其中进行数据收集(甚至可能进行一些转换)以外的复杂逻辑。可以在其中放置一些数据按摩逻辑,或者将多个查询的结果聚合在一起。就是这样。超出此范围的任何内容都应视为应该驻留在其他地方的业务逻辑。
不要将它们用作防御SQL注入的唯一机制。您可以将它们留在这里,以防万一有坏事发生,但是在它们前面应该有一系列防御性逻辑-客户端验证/清理,服务器端验证/清理,可能转换成对您有意义的类型域模型,最后传递给参数化的语句(可以是参数化的SQL语句或参数化的存储过程。)
不要使数据库成为唯一包含存储过程的地方。您应该像对待C#或Java源代码一样对待您的商店proc。也就是说,源代码控制您存储过程的文本定义。人们对存储过程的抱怨不能被源代码控制-废话,他们只是不知道他们在说什么该死的地狱。
我对如何/在何处使用它们的看法
您的应用程序需要从多个查询或视图中转置或聚合的数据。您可以将其从应用程序卸载到数据库中。在这里,您必须进行性能分析,因为a)数据库引擎在执行这些操作方面比应用程序服务器更有效,但是 b)(有时)应用程序服务器更易于水平扩展。
细粒度的访问控制。您不希望某些笨蛋在数据库中运行笛卡尔联接,但是您不能仅仅禁止人们像这样执行任何SQL语句。一种典型的解决方案是允许在开发和UAT环境中使用任意SQL语句,而在systest和生产环境中禁止使用它们。任何必须使其进入systest或生产环境的语句都会进入存储过程,由开发人员和dbas进行代码审查。
运行不在存储过程中的SQL语句的任何有效需求都将通过不同的用户名/帐户和连接池(对使用情况进行高度监视和劝阻)。
- 在像Oracle这样的系统中,您可以访问LDAP或创建到外部数据库的符号链接(例如,通过vpn在业务伙伴的db上调用存储过程。)执行意大利面条式代码的简便方法,但这对于所有编程范例都是正确的,有时您有特定的业务/环境要求,这是唯一的解决方案。Store proc有助于将这种烦恼单独封装在一个地方,靠近数据,而不必遍历应用服务器。
您是在数据库上作为存储过程还是在应用服务器上运行此程序,取决于工程师(工程师)必须进行的权衡分析。两种选择都必须进行分析,并通过某种类型的分析进行论证。通过简单地指责另一种替代方法是“不好的做法”而走了一条路,这只是一个la脚的工程解决方案。
- 在您根本无法扩展应用服务器的情况下(例如,没有新硬件或云实例的预算),但是数据库后端具有足够的容量(这是很多人都愿意承认的典型情况),移动业务逻辑以存储proc。它不漂亮,可能会导致贫乏的领域模型……但随后又要……权衡分析,这是大多数软件黑客都难以接受的事情。
无论这是否成为永久性解决方案,这都是特定于该特定时刻观察到的约束。
希望能帮助到你。