【问题标题】:Oracle Stored Procedures that Return a Dataset返回数据集的 Oracle 存储过程
【发布时间】:2016-08-19 09:29:45
【问题描述】:

我是 Microsoft 堆栈(C#、SQL Server、EF 等)的开发人员,我继承了一个连接到 Oracle 11g 数据库的 webforms 应用程序。该应用程序当前包含我想将其转换为参数化存储过程的内联 SQL 语句。然而,由于习惯了 T-SQL,我发现转向 PL/SQL 的学习曲线相当陡峭。

大多数 SQL 语句都是相当简单的语句,它们从基表中返回过滤后的数据集

select field1, field2, fieldn 
from foo 
where field1 = 'blah'

在 T-SQL 中,这相当简单

create procedure fooproc
  @filter varchar(100)
as
begin
    select field1, field2, field3 
    from foo 
    where field1 = @filter
end

不幸的是,在 PL/SQL 中似乎没有这么简单。经过搜索,我找到了以下答案:

  1. 使用函数而不是过程(这让我想知道 SQL Server 中的过程是否一对一映射到 Oracle 中的过程)
  2. 为程序创建一个“包”(仍然不太清楚那是什么)
  3. 使用游标或 for 循环(这看起来很邪恶而且完全错误)

此外,我在网上找到的大多数 Oracle 存储过程示例都返回一个标量值或根本没有值。我认为这是许多人想要执行的一项相当普遍的任务,但我的 google-fu 在这方面一定不是很强。因此,如果有人可以帮助我翻译,我将不胜感激。

谢谢

【问题讨论】:

  • 只是好奇为什么要将现有 SQL(可能也适用于 Oracle,取决于)转换为存储过程调用,尤其是如果您不习惯编写 pl/sql(还有其他原因)为什么直接 SQL 比存储过程更受欢迎)。
  • 有几个原因。首先也是最重要的是,如果格式不正确,内联 sql 很容易受到 sql 注入攻击。我想这样做的另一个主要原因是关注点分离。我想将我的数据逻辑存放在数据库中,以便使用为 sql 调试而设计的工具更容易阅读和调试。
  • 我的问题是因为你似乎提出的是一个 TAPI 设计,这在我看来是一个坏主意(而不是从表 a 中选择 x,y,z 你必须调用一些函数) .有关 TAPI 和 XAPI 的更多讨论,请参阅 this post。另一个有趣的讨论(Tom Kyte 和 Steve Feurstein)是here。这些链接中有很多信息!享受吧。

标签: asp.net oracle stored-procedures oracle11g


【解决方案1】:

只返回结果集的 SQL Server 存储过程最自然地会转换为返回游标的 Oracle 存储函数。类似的东西

CREATE OR REPLACE FUNCTION fooFunc( p_field1 IN foo.field1%type )
  RETURN sys_refcursor
IS
  l_rc sys_refcursor;
BEGIN
  OPEN l_rc
   FOR SELECT field1, field2, field3
         FROM foo
        WHERE field1 = p_field1;
  RETURN l_rc;
END;

在 Oracle 12.1 中,有一些 syntactic sugar for implicit results 通过允许过程隐式返回 ref 游标来简化从 SQL Server 的转换,但您的问题表明您仍在使用 11g,因此这可能不是一个选项。

您还可以有一个具有out 参数类型为sys_refcursor 的过程。不过,通常情况下,您应该对仅返回结果的对象使用函数,对修改数据的对象使用过程。

通常情况下,您的所有 Oracle 过程和函数都将被打包到包中,这些包将一些相关功能组合在一起。如果您有六个函数可以让您使用不同的条件查询 foo,那么您可能希望将所有这些函数放在一个包中,以便让事情井井有条。

【讨论】:

  • 我一直模糊了 mssql 中函数和过程之间的界限,因为函数可以返回标量值和表值。我想这也涉及到甲骨文。我会试一试。我很惊讶这是多么难以挖掘,因为每个曾经编写过数据驱动 Web 应用程序的 .net 开发人员都必须编写 CRUD 代码才能与数据库对话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
  • 2016-04-09
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多