4

在 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)

希望描述足够清楚...

4

1 回答 1

2

不幸的是,T-SQL 没有像 Oracle 的包、包变量或变量结构这样的东西。哦,它做到了。

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

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

于 2013-08-07T23:22:40.660 回答