4

Oracleには、これらのプロシージャで使用されるすべての変数を基本的に格納(カプセル化)および初期化するパッケージを使用する多くのストアドプロシージャがあります。パッケージには、すべてのパッケージ変数の初期化を処理する関数も 1 つあります。

私の質問は、これを 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 で実現する最も簡単な方法です。

# テーブルを使用できます。つまり、すべての変数を含む #params テーブルを f_get_parms に作成し、その # テーブルを他のすべてのプロシージャで使用してそれらを取得します。欠点は、呼び出しプロシージャで変数を宣言するか、DML を使用して # テーブルの列にアクセスする必要があることです。これは、変数として持つよりもはるかに面倒です。

私が以前に使用した別の方法は、XML を使用して複数の変数を渡し、それらを 1 つの変数として扱うことです。変数にアクセスするよりも値にアクセスするほうが面倒ですが、プロシージャの代わりに関数を使用して値を取得できるという利点があります。

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 に答える