【问题标题】:How to translate Oracle package to SQL Server?如何将 Oracle 包翻译成 SQL Server?
【发布时间】:2013-08-09 02:20:36
【问题描述】:

在 Oracle 中,我有很多使用一个包的存储过程,该包基本上存储(封装)和初始化这些过程使用的所有变量。包中还有一个函数负责初始化它的所有包变量。

我的问题是:如何将它移植到 SQL Server?

我的第一次尝试是声明所有包变量并将它们用作过程的 OUTPUT 参数来初始化它们,但是我需要在使用它们的每个过程中一遍又一遍地声明这些变量(并且有很多包装内)。在 SQL Server 上是否有更好(和 DRY)的方法来执行此操作?

一些代码来解释它:

甲骨文:

包装:

create or replace 
PACKAGE MYPARAMS AS 

  /**
  param container 
  */
  type rc_params is record
  (
    var1 varchar2(30),
    var2 integer
  );
  /**
  init param container
  use: v_params rc_pkp_plan_params := MYPARAMS.f_get_params(initvar)
  */
  function f_get_params(initvar number) return rc_params;

END MYPARAMS;
/

包体:

CREATE OR REPLACE
PACKAGE BODY MYPARAMS AS

  function f_get_params(initvar number) return rc_params AS
    retval rc_params;
  BEGIN
    retval.var1 := 'MY_VAR1';
    retval.var2 := initvar;
    return retval;
  END f_get_params;

END MYPARAMS;
/

一些用法示例:

declare
  initvar integer := 22;
  v_params MYPARAMS.rc_params := MYPARAMS.f_get_params(initvar);
begin
  dbms_output.put_line(v_params.var1 || ' initialized by ' || v_params.var2);
end;

SQL 服务器:

if exists (select * from sysobjects where id = object_id('f_get_params'))
  drop procedure f_get_params
go
create  procedure  f_get_params(
    @initvalue integer,
    @var1 varchar(30) OUTPUT,
    @var2 integer OUTPUT
)
as
    set @var1 = 'MYVAR1'
    set @var2 = @initvalue
go  

-- this block i would like to avoid:
declare 
    @initvalue integer = 33,
    @var1 varchar(30),
    @var2 integer

exec f_get_params @initvalue, @var1 OUTPUT, @var2 OUTPUT
print @var1 + ' initialized by ' + convert(varchar(2), @var2)

希望描述足够清楚...

【问题讨论】:

  • 您不喜欢declare @initvalue integer = 33, var1 varchar(30), @var2 integer 部分,具体来说?
  • 是的,因为我在几乎所有程序中都需要这些变量。因此我想封装这些变量和(对我来说最重要的)它们的初始化。

标签: sql-server oracle tsql plsql package


【解决方案1】:

不幸的是,T-SQL 没有像 Oracle 的包、包变量或变量结构这样的东西。哦,原来如此。

您所做的可能是在 T-SQL 中完成它的最简单方法,即使它确实需要复制变量。

您可以使用 # 表,即在 f_get_parms 中创建一个包含所有变量的 #params 表,然后在所有其他 procs 中使用该 # 表来检索它们。缺点是您仍然必须在调用过程中声明变量,或者使用 DML 访问 # 表中的列,这比将它们作为变量要麻烦得多。

我之前使用的另一种方法是使用 XML 传递多个变量,但将它们视为一个变量。访问值仍然比访问变量更麻烦,但它的优点是允许您使用函数而不是过程来获取值。

CREATE FUNCTION dbo.uf_get_params (
  @initvar int
)
RETURNS xml
AS
BEGIN
  DECLARE @xml xml,
          @var1 varchar(30) = 'MYVAR'    -- setting value on DECLARE requires SQL2008+

  SELECT @xml = (SELECT @var1 AS var1,
                        @initvar AS initvar
                    FOR XML RAW('params'))

  RETURN @xml
END
go

在你的调用过程中,你会有

DECLARE @params xml = (SELECT dbo.uf_get_parms(12))

要获取参数,然后使用标准 XML/XQUERY 函数从 @params XML 变量中检索各个变量(属性)。

【讨论】:

  • 好主意,我没有想到 vartype XML。我试试这个。
  • 我按照建议做了,因为它似乎是在 SQL Server 中“打包”东西的唯一方法
猜你喜欢
  • 2019-02-23
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多