いくつかのパラメーターを含むストアドプロシージャを使用する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では、次のようなエラーが発生します。
'、'の近くに不正な構文
区切り文字の代わりに,
区切り文字が文字列に含まれているようです
次の3つが必要です。
SSRSデータセットのプロパティで、複数値のパラメーターをコンマ区切りの文字列としてストアドプロシージャに渡します
=Join(Parameters!TerritoryMulti.Value, ",")
SQL Serverでは、カンマ区切りの文字列を分割してミニテーブルに戻すことができるテーブル値関数が必要です(例 ここを参照 )。編集:SQL Server 2016以降、組み込み関数STRING_SPLIT
を使用できます
ストアドプロシージャで、次のようなwhere句を使用します。
WHERE sometable.TerritoryID in (select Item from dbo.ufnSplit(@TerritoryMulti,','))
...ここで、ufnSplit
はステップ2の分割関数です。
(私のブログ記事の完全な手順とコード ' 失敗の少ないSSRS複数値パラメーター '):
複数値リストがあると仮定しましょう_@param1
_
SSRSレポートに_@param2
_という別の内部パラメーターを作成し、デフォルト値を次のように設定します。
_=Join(Parameters!param1.value, 'XXX')
_
XXX
には、コンマを除いて任意の区切り文字を使用できます(下記を参照)
次に、_@param2
_をクエリまたはストアドプロシージャに渡すことができます。
他の方法で実行しようとすると、コンマを使用して引数を区切る文字列関数が失敗します。 (例:CHARINDEX、REPLACE)。
たとえば、Replace(@param2, ',', 'replacement')
は機能しません。 「置換関数には3つの引数が必要です」などのエラーが発生します。
最後に、この問題の簡単な解決策を得ることができました。以下に、私が従ったすべての(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)
私は自分の解決策の簡単な方法を見つけました。レポートのパラメーター値を次のような式として定義します
="'" + 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
は、ストアドプロシージャパラメータの名前です。
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」と一致しません。