22

我有一个 SQL Server 数据库,其中包含大量存储过程。由于 Oracle 的“包”特性,大量存储过程在我的 Oracle 数据库中不是问题。

程序员如何解决缺少像 Oracle 那样的“包”特性的问题?

4

9 回答 9

29

虽然 SQL Server 没有像您习惯的那样通过封装和包状态的“酷特性”提供任何东西,但您可以将存储过程组织成模式。

在企业管理器中,这些 proc 仍然全部列在一起,如果您有数百个 proc,这将构成一个巨大的树状列表。我也很怀念 Oracle 包的组织和很酷的特性。但是,所有平台都有其优势。

注意:用 .NET 语言编写存储过程确实可以提供封装和状态。然而,它仍然没有以任何特殊方式在 EM 树视图中将它们分开。

于 2009-04-21T00:08:31.093 回答
15

想出一个好的命名约定,使用它,并执行它。

于 2009-04-20T22:11:38.363 回答
8

模式可用于组织存储过程和其他对象。就个人而言,当它们按功能区域组织对象时,我更喜欢使用模式,并且这些功能区域对应于安全边界。在 AdventureWorks 示例数据库中可以找到这方面的一个示例,该数据库具有“人力资源”和“销售”等模式。理论是给定用户可能需要访问“人力资源”中的对象,但可能不需要访问“销售”信息。

正如詹姆斯上面所说,另一种方法是使用命名约定并强制执行它。我将补充一点,SQL Server Management Studio 有一个过滤器按钮,可用于过滤显示的对象列表。例如,可以单击“存储过程”文件夹并过滤名称包含“添加”。

在我当前的项目中,我已经从 SSIS 包中提取了一些 SQL 查询并将其放入存储过程中。为了区分这些存储过程和那些应该通用的存储过程,我在名称前加上了“ssis”。如果我可以在 C# 或 C++ 中创建类似于命名空间的东西,并创建“SSIS.SelectUserLookupData”而不是“ssis_SelectUserLookupData”,那肯定会更令人愉快。如果这些命名空间可以嵌套,那就更好了。

如果这是 Oracle 中 Packages 的功能之一,那么也许有人会告诉我。

于 2009-04-21T01:50:20.803 回答
7

我曾使用过 SQL Server 和 Oracle,因此看到了两者的优缺点。由于上述评论有点激烈,我会尽量保持中立......

那么,什么是 Oracle 包?把它想象成一个数据库类

Package 有两个元素:头文件和正文文件。头文件是您的公共接口,包含所有可直接调用的存储过程或函数(在 Oracle 中函数返回值,存储过程不返回值)的签名(名称、参数和返回类型,如果适用)。包体必须实现包头文件中的所有过程签名。

包的主体元素包含所有实际执行工作的存储过程和逻辑。您可能在包头中声明了一个保存过程,该过程调用主体中存在的插入或更新过程。开发人员只能看到“保存”过程。重要的是要记住,包体也可以实现未在包头中声明的过程或函数,它们只是无法在包本身之外访问。

我发现软件包非常有用,原因有很多:

  1. 您已经了解了可以提供给其他开发人员的公共接口的概念
  2. 包可以镜像你编译的类。我的 Orders.Save() C# 方法将调用我的 Oracle Orders.SaveLineItem 方法来保存每个行项目,并调用 Oracle SaveOrder 方法来保存订单摘要详细信息。
  3. 我的 proc 在包内以一种很好的、​​合乎逻辑的方式组合在一起

就个人而言,我希望 MS 能够实现某种包功能,因为我认为它可以使数据库更加干净。

于 2009-08-07T12:47:53.207 回答
2

未提及的包装的另一项功能是“包裹”身体的能力。标头始终是公开的,任何有权执行包的人都可以查看。但这也允许他们查看正文中的代码。您可以包装主体,对其进行加密,并防止任何人看到代码实际在做什么。它是一个很好的功能,安全性是一个大问题。

于 2013-08-21T13:29:19.407 回答
1

3) 反对 oracle 包的最佳论据是,根据 Ask Tom 网站上的经验和研究,如果不将包脱机,就无法更新包。这是无法接受的。使用 SQL Server,我们可以在不中断生产操作的情况下即时更新存储过程。

我理解这种说法的挫败感,但我不会称 id 为“不可接受的”。在真实的生产环境中,永远不应该在生产环境中测试更改。更新应按计划有序地从测试环境转移到生产环境。在 24/7 系统中,冗余生产环境应在服务器更新时处理停机时间。不仅包必须脱机,而且新包如果未编译,则在重新联机时将失败。Oracle 数据库需要一个 DBA 元素。但是,我确实想念 Oracle 软件包。

于 2013-01-03T15:04:46.083 回答
1

看到一个人如何情绪化地克服这样一个枯燥的话题,这有点有趣。Oracle 有一个特性,SQL Server 似乎并没有对这个特性的有争议的特性产生各种反应。

对于初学者来说,问题在于风格:Oracle 中的这个特性在 SQL Server 中被遗漏了,推荐的方法是什么。

无需为此情绪激动。

对于那些不喜欢 Oracle 中的打包功能的人——无论出于何种原因——他们仍然可以像使用 SQL Server 那样做。

更详细地讲,样式中可能会有一个后续问题:当修改包中的函数或过程时,整个包都无效并且这“糟透了”,推荐的避免吸吮方面的方法是什么.

就个人而言,我从未见过有人抱怨无法修改可执行文件中的静态链接库而无需重新链接它。

于 2020-05-21T18:16:47.163 回答
0
  1. 就像人们所说的那样,Schema 是一种更符合逻辑且更符合 ANSI 的组织数据库表和过程的方式。

  2. 软件工程的最佳实践是我们永远不应该直接在任何服务器上进行更改。由于所有数据库存储过程都是脚本化的并且在配置控制下,我们可以将这些脚本安排到我们想要的任何文件夹结构中。

(来自 AskTom 的过时信息已被删除)

于 2012-03-09T19:55:29.450 回答
-2

我要感谢我的幸运星,SQL Server 没有包。Oracle 软件包很烂。

嗯,我们需要一种方法来处理所有这些程序并将它们放在一个地方。我知道!让我们让开发人员为每个包创建和维护两个文件。他们会永远爱我们!

只要 MS 从未像 Oracle 那样实现软件包,在我看来这就是胜利。

编辑评论者:

Oracle 包只是一种将存储过程组织成包的方法,这样您就没有 100 个存储过程,而是可能有 5 个包。它们不像 Java 或 C# 代码中的包那样可堆叠。所有软件包都处于同一级别。

一个包需要两个文件:头文件和正文文件。这在将新过程添加到现有包时会产生挫败感,因为如果不添加标头就无法添加主体,即使它包含与主体中完全相同的信息。

例如,这是我的一个包的头文件中的一个片段:

    PROCEDURE bulk_approve_events
(
    i_last_updated_by IN VARCHAR2,
    o_event OUT NUMBER
);

这是正文中的相应过程:

    PROCEDURE bulk_approve_events
(
    i_last_updated_by IN VARCHAR2,
    o_event OUT NUMBER
) IS
...
BEGIN
...
END;

没有不同。头文件是无用的,只是开发人员在使用包进行开发时要跨越的另一个障碍。在我的项目中,我们有一个约定,每个过程的所有注释文档都放在标题中,以及添加时间和添加者的详细信息,但这也可以很容易地包含在正文中。

于 2009-04-21T20:19:01.510 回答