web-dev-qa-db-ja.com

ストアドプロシージャを使用したSSRS多値パラメーター

いくつかのパラメーターを含むストアドプロシージャを使用するSSRSレポートに取り組んでいます。複数のアイテムを選択するオプションが必要なため、2つのパラメーターに問題があります。

ここに私が持っているものの要約版があります:

CREATE PROCEDURE [dbo].[uspMyStoredProcedure] 
  (@ReportProductSalesGroupID AS VARCHAR(MAX) 
  ,@ReportProductFamilyID AS VARCHAR(MAX)
  ,@ReportStartDate AS DATETIME
  ,@ReportEndDate AS DATETIME)

--THE REST OF MY QUERY HERE WHICH PULLS ALL OF THE NEEDED COLUMNS

WHERE DateInvoicedID BETWEEN @ReportStartDate AND @ReportEndDate
AND ProductSalesGroupID IN (@ReportProductSalesGroupID)
AND ProductFamilyID IN (@ReportProductFamilyID)

ストアドプロシージャを実行しようとすると、@ReportProductSalesGroupIDに1つの値と1つの値@ReportProductFamilyIDのみを入力した場合にのみ、値が返されます。 2つのSalesGroupIDや2 ProductFamilyIDを入力しようとしてもエラーにはなりませんが、何も返されません。

-- Returns data
EXEC uspMyStoredProcedure 'G23',     'NOF',     '7/1/2009', '7/31/2009'

-- Doesn't return data
EXEC uspMyStoredProcedure 'G23,G22', 'NOF,ALT', '7/1/2009', '7/31/2009'

SSRSでは、次のようなエラーが発生します。

'、'の近くに不正な構文

区切り文字の代わりに,区切り文字が文字列に含まれているようです

21
user153949

次の3つが必要です。

  1. SSRSデータセットのプロパティで、複数値のパラメーターをコンマ区切りの文字列としてストアドプロシージャに渡します

    =Join(Parameters!TerritoryMulti.Value, ",")
    
  2. SQL Serverでは、カンマ区切りの文字列を分割してミニテーブルに戻すことができるテーブル値関数が必要です(例 ここを参照 )。編集:SQL Server 2016以降、組み込み関数STRING_SPLITを使用できます

  3. ストアドプロシージャで、次のようなwhere句を使用します。

    WHERE sometable.TerritoryID in (select Item from dbo.ufnSplit(@TerritoryMulti,','))
    

    ...ここで、ufnSplitはステップ2の分割関数です。

(私のブログ記事の完全な手順とコード ' 失敗の少ないSSRS複数値パラメーター '):

41
codeulike

複数値リストがあると仮定しましょう_@param1_

SSRSレポートに_@param2_という別の内部パラメーターを作成し、デフォルト値を次のように設定します。

_=Join(Parameters!param1.value, 'XXX')
_

XXXには、コンマを除いて任意の区切り文字を使用できます(下記を参照)

次に、_@param2_をクエリまたはストアドプロシージャに渡すことができます。

他の方法で実行しようとすると、コンマを使用して引数を区切る文字列関数が失敗します。 (例:CHARINDEX、REPLACE)。

たとえば、Replace(@param2, ',', 'replacement')は機能しません。 「置換関数には3つの引数が必要です」などのエラーが発生します。

6
Ian Fry

最後に、この問題の簡単な解決策を得ることができました。以下に、私が従ったすべての(3)ステップを示しました。

みんなが気に入ってくれることを願っています:)

手順1-1つの列を持つグローバル一時テーブルを作成しました。

CREATE GLOBAL TEMPORARY TABLE TEMP_PARAM_TABLE(
  COL_NAME  VARCHAR2(255 BYTE)
) ON COMMIT PRESERVE ROWS NOCACHE;

ステップ2-分割手順では、配列やデータテーブルを使用せず、分割した値をグローバル一時テーブルに直接ロードしました。

CREATE OR REPLACE PROCEDURE split_param(p_string IN VARCHAR2 ,p_separator IN VARCHAR2
)
IS
   v_string VARCHAR2(4000);
   v_initial_pos NUMBER(9) := 1;
   v_position NUMBER(9) := 1;
BEGIN
   v_string := p_string || p_separator;

   delete from temp_param_policy;

   LOOP
      v_position :=
                  INSTR(v_string, p_separator, v_initial_pos, 1);
      EXIT WHEN(NVL(v_position, 0) = 0);

      INSERT INTO temp_param_table
           VALUES (SUBSTR(v_string, v_initial_pos
                         , v_position - v_initial_pos));

      v_initial_pos := v_position + 1;
   END LOOP;
commit;

END split_param;
/

ステップ3-SSRSデータセットパラメータで、私は使用しました

=Join(Parameters!A_COUNTRY.Value, ",")

手順4:ストアドプロシージャの開始時にプロシージャを実行する

Exec split_param(A_Country, ‘,’);

ステップ5:ストアドプロシージャsqlで、次のような条件を使用します。

Where country_name in (select * from TEMP_PARAM_TABLE)
1
Sasidhar Nalla

私は自分の解決策の簡単な方法を見つけました。レポートのパラメーター値を次のような式として定義します

="'" + Join(Parameters!parm.Value,"','") + "'"

(読み込めない場合、最初と最後のリテラルは二重引用符、単一引用符、二重引用符です。結合リテラルは二重引用符、単一引用符、コンマ、単一引用符、二重引用符です)

次に、ストアドプロシージャで動的SQLを使用してステートメントを作成できます。次のように、後のクエリで結合する値の一時テーブルを作成するためにこれを行いました。

CREATE #nametable (name nvarchar(64))

SET @sql = N'SELECT Name from realtable where name in (' + @namelist + ')'

INSERT INTO #nametable exec sp_executesql @sql

@namelistは、ストアドプロシージャパラメータの名前です。

0
Thomas Carroll

SSRSがパラメーターを渡すときは、Param1、Param2、Param3の形式です。

この手順では、各パラメーターの周囲に識別子を配置するだけです。また、データセットによって返される値の周囲の識別子。私の場合、セミコロンを使用しました。

CREATE OR REPLACE PROCEDURE user.parameter_name ( i_multivalue_parameter ) AS l_multivalue_parameter varchar2(25555) := ';' || replace(i_multivalue_parameter,',',';') || ';'; BEGIN select something from dual where ( instr(l_multivalue_parameter, ';' || database_value_that_is_singular || ';') > 0 ) END;

i_multivalue_parameterはSSRSを介して渡されます。

l_multivalue_parameterは、SSRSを介して渡されたパラメーターを読み取り、各値の周囲に識別子を配置します。

database_value_that_is_singularは、各レコードに対して返される値です。

したがって、 'Type1、Type2、Type3'がSSRS経由で渡される場合:

i_multivalue_parameterは、Type1、Type2、Type3です。

l_multivalue_parameterは:; Type1; Type2; Type3;

database_value_that_is_singularは:; Type1;または; Type2;または; Type3;

パラメータが一致する場合、Instrは0を超える値を返します。

これは、各パラメーターが類似していても機能します。 EG:「タイプA」および「タイプAA」。つまり、「タイプA」は「タイプAA」と一致しません。

0
Eneerge