如何将Oracle包转换为SQL Server?

时间:2013-08-07 15:49:20

标签: sql-server oracle tsql plsql package

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

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

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

一些代码来解释它:

ORACLE

包裹:

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 Server:

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)

希望描述足够清楚......

1 个答案:

答案 0 :(得分:2)

不幸的是,T-SQL没有像Oracle的包,包变量或变量结构那样的东西。哦它确实如此。

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

您可以使用#表,即在f_get_parms中创建一个包含所有变量的#params表,然后在所有其他过程中使用该表来检索它们。缺点是您仍然要么必须在调用过程中声明变量,要么使用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变量中检索单个变量(属性)。