web-dev-qa-db-ja.com

Reporting Servicesの単一パラメーターに複数の値を渡す

レポートに複数選択パラメーターがあります。 Webクエリ文字列の単一のパラメータに複数の値を渡す方法を見つけようとしていますか?単一の値を渡すと、正常に機能します。

レポートは、単一のパラメーターに対して複数の選択肢を選択して正常に実行されます。私の問題はWebクエリ文字列にあります。

John Sansomのソリューションは機能しますが、これを行う別の方法があります。潜在的に非効率的なスカラー値のUDFを使用する必要はありません。 SSRSレポートで、クエリ定義の[パラメーター]タブで、パラメーター値を

=join(Parameters!<your param name>.Value,",")

クエリでは、次のように値を参照できます。

where yourColumn in (@<your param name>)
97
Ed Harper

これは、複数選択パラメーターを別の複数選択パラメーターに渡すときに使用するものです。

=SPLIT(JOIN(Parameters!<your param name>.Value,","),",")
43
Minks

これは、SQL Reporting Servicesでサポートされていない機能の1つです。

必要なことは、選択したすべてのアイテムを単一の文字列としてストアドプロシージャに渡すことです。文字列内の各要素はコンマで区切られます。

次に、提供された文字列をテーブルとして返す関数を使用して文字列を分割します。下記参照。

ALTER FUNCTION [dbo].[fn_MVParam]
   (@RepParam nvarchar(4000), @Delim char(1)= ',')
RETURNS @Values TABLE (Param nvarchar(4000))AS
  BEGIN
  DECLARE @chrind INT
  DECLARE @Piece nvarchar(100)
  SELECT @chrind = 1 
  WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR))
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam) - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
  RETURN
  END

その後、次のようにメインクエリのwhere句で結果を参照できます。

where someColumn IN(SELECT Param FROM dbo.fn_MVParam(@sParameterString,','))

この解決策があなたのお役に立てば幸いです。ご質問がある場合は、お気軽にお問い合わせください。

乾杯、ジョン

21
John Sansom

ジョン・サンソムとエド・ハーパーには素晴らしい解決策があります。ただし、IDフィールド(つまり、整数)を処理するときにそれらを機能させることができませんでした。以下の分割関数を変更して、値を整数としてキャストし、テーブルが主キー列と結合するようにしました。区切りリストの順序が重要な場合に備えて、コードにコメントを付け、順序の列を追加しました。

CREATE FUNCTION [dbo].[fn_SplitInt]
(
    @List       nvarchar(4000),
    @Delimiter  char(1)= ','
)
RETURNS @Values TABLE
(
    Position int IDENTITY PRIMARY KEY,
    Number int
)

AS

  BEGIN

  -- set up working variables
  DECLARE @Index INT
  DECLARE @ItemValue nvarchar(100)
  SELECT @Index = 1 

  -- iterate until we have no more characters to work with
  WHILE @Index > 0

    BEGIN

      -- find first delimiter
      SELECT @Index = CHARINDEX(@Delimiter,@List)

      -- extract the item value
      IF @Index  > 0     -- if found, take the value left of the delimiter
        SELECT @ItemValue = LEFT(@List,@Index - 1)
      ELSE               -- if none, take the remainder as the last value
        SELECT @ItemValue = @List

      -- insert the value into our new table
      INSERT INTO @Values (Number) VALUES (CAST(@ItemValue AS int))

      -- remove the found item from the working list
      SELECT @List = RIGHT(@List,LEN(@List) - @Index)

      -- if list is empty, we are done
      IF LEN(@List) = 0 BREAK

    END

  RETURN

  END

前述のとおり、この関数を使用します。

WHERE id IN (SELECT Number FROM dbo.fn_SplitInt(@sParameterString,','))
9
CodeGrue

Oracle:

「IN」フレーズ(Ed's Solution)は、Oracle接続(少なくともバージョン10)に対して機能しません。しかし、この簡単な回避策が見つかりました。データセットのパラメーターのタブを使用して、複数値パラメーターをCSVに変換します。

    :name =join(Parameters!name.Value,",")

次に、SQLステートメントのWHERE句でinstring関数を使用して一致を確認します。

    INSTR(:name, TABLE.FILENAME) > 0
5
Jeff

そうでなければ素晴らしいfn_MVParamで問題に遭遇しました。 SSRS 2005は、2つの引用符としてアポストロフィを含むデータを送信しました。

これを修正するために1行追加しました。

select @RepParam = replace(@RepParam,'''''','''')

私のバージョンのfnもnvarcharではなくvarcharを使用しています。

CREATE FUNCTION [dbo].[fn_MVParam]
   (
    @RepParam varchar(MAX),
    @Delim char(1)= ','
   )
RETURNS @Values TABLE (Param varchar(MAX)) AS
/*
  Usage:  Use this in your report SP 
     where ID in (SELECT Param FROM fn_MVParam(@PlanIDList,','))
*/

BEGIN

   select @RepParam = replace(@RepParam,'''''','''')
   DECLARE @chrind INT
   DECLARE @Piece varchar(MAX)
   SELECT @chrind = 1
   WHILE @chrind > 0
      BEGIN
         SELECT @chrind = CHARINDEX(@Delim,@RepParam)
         IF @chrind > 0
            SELECT @Piece = LEFT(@RepParam,@chrind - 1)
         ELSE
            SELECT @Piece = @RepParam
         INSERT @VALUES(Param) VALUES(@Piece)
         SELECT @RepParam = RIGHT(@RepParam,DATALENGTH(@RepParam) - @chrind)
         IF DATALENGTH(@RepParam) = 0 BREAK
      END
   RETURN
END
4
Bob Amy

優れたジョンソリューションの修正、解決:

  • 「2つの引用符」エラー
  • パラメータ内のピースの1つ後のスペース

    
    ALTER FUNCTION [dbo].[fn_MVParam]
    (@RepParam nvarchar(4000), @Delim char(1)= ',')
    RETURNS @Values TABLE (Param nvarchar(4000))AS
    BEGIN
    //2 quotes error
    set @RepParam = replace(@RepParam,char(39)+char(39),CHAR(39))
    DECLARE @chrind INT
    DECLARE @Piece nvarchar(100)
    SELECT @chrind = 1 
    WHILE @chrind > 0
    BEGIN
      SELECT @chrind = CHARINDEX(@Delim,@RepParam)
      IF @chrind  > 0
        SELECT @Piece = LEFT(@RepParam,@chrind - 1)
      ELSE
        SELECT @Piece = @RepParam
      INSERT  @Values(Param) VALUES(CAST(@Piece AS VARCHAR(300)))
      //space after one of piece in parameter: LEN(@RepParam + '1')-1
      SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam + '1')-1 - @chrind)
      IF LEN(@RepParam) = 0 BREAK
    END
    RETURN
    END
    
3
grum

したがって、テキスト値を乗算すると、= join(Parameters!Customer.Value、 "'、'")を使用したそれぞれを単一引用符で囲むクエリになります。そのため、「。Value」の後には、カンマ、ダブルクォート、シングルクォート、コンマ、シングルクォート、ダブルクォート、クローズブラケットがあります。シンプル:)

1
RichardBSmith

以下のソリューションは私のために働いた。

  1. データセットプロパティのパラメータータブで、式アイコン(! http://chittagongit.com//images/fx-icon/fx-icon-16.jpg [fx symbol])をクリックしますコンマ区切りのエントリを許可する必要があるパラメーター。

  2. 表示される式ウィンドウで、分割機能を使用します(共通機能->テキスト)。以下に例を示します。

= Split(Parameters!ParameterName.Value、 "、")

1
sherebry

最初にテーブルに複数の値を追加してから、(ワイルドカードを使用しても)好きなものを結合したり、後で使用するために別のテーブルにデータを保存したり(または別のテーブルに値を追加)できます。

データセットの式を使用してパラメーター値を設定します:

="SELECT DISTINCT * FROM (VALUES('" & JOIN(Parameters!SearchValue.Value, "'),('") & "')) 
AS tbl(Value)"

クエリ自体:

DECLARE @Table AS TABLE (Value nvarchar(max))

INSERT INTO @Table EXEC sp_executeSQL @SearchValue 

ワイルドカードの例:

SELECT * FROM YOUR_TABLE yt 

INNER JOIN @Table rt ON yt.[Join_Value] LIKE '%' + rt.[Value] + '%'

動的SQLを使用せずにそれを実行する方法を見つけ出したいと思いますが、SSRSが実際のクエリにパラメーターを渡す方法が原因で機能しないと思います。誰かがよく知っているなら、私に知らせてください。

1
jon

これは、結合関数を使用して複数値パラメーターを保存し、後でデータベースからまったく同じ選択を復元することです。

パラメーターを保存する必要があるという要件のあるレポートを作成しました。レポートを再度開くと(レポートにOrderIDパラメーターが渡されます)、以前にユーザーが選択した値をもう一度選択する必要があります。

このレポートでは、12個のパラメーターの半分を使用し、各パラメーターには独自のデータセットと結果のドロップダウンリストがありました。パラメーターは、最終選択の範囲を狭めるために以前のパラメーターに依存しており、レポートが「表示」されると、格納するためにストアドプロシージャが呼び出されました。

ストアドプロシージャは、レポートから渡された各パラメーターを受け取りました。データベースのストレージテーブルをチェックして、そのOrderIDにパラメーターが保存されているかどうかを確認しました。そうでない場合は、すべてのパラメーターを保存しました。その場合、その注文のすべてのパラメーターが更新されます(これは、ユーザーが後で気が変わった場合です)。

レポートを実行すると、データセットdsParametersがあります。このデータセットは、SQLテキストであり、そのorderIDがある場合はその単一の行を選択します。レポートの各パラメーターは、このデータセットからデフォルト値を取得し、そのパラメーター専用のデータセットから選択リストを取得します。

複数選択パラメーターで問題が発生しました。メインデータセットパラメーターリストでjoin(@Value、 "、")コマンドを使用し、コンマ区切りの文字列をストアドプロシージャに渡しました。しかし、それを復元する方法は?コンマ区切りの文字列をパラメーターのデフォルト値ボックスにフィードバックすることはできません。

あなたが話しているのと同様の方法で、パラメータを分割する別のデータセットを作成する必要がありました。次のようになります。

IF OBJECT_ID('tempdb..#Parse','U') IS NOT NULL DROP TABLE #Parse

DECLARE @Start int, @End int, @Desc varchar(255)

SELECT @Desc = fldDesc FROM dbCustomData.dbo.tblDirectReferralFormParameters WHERE fldFrom = @From and fldOrderID = @OrderID

CREATE TABLE #Parse (fldDesc varchar(255))

SELECT @Start = 1, @End = 1

WHILE @End > 0
    BEGIN
        SET @End = CHARINDEX(',',@Desc,@Start)
        IF @End = 0 
            BEGIN
                INSERT #Parse SELECT REPLACE(SUBSTRING(@Desc,@Start,LEN(@Desc)),',','') AS fldDesc 
                BREAK
            END
        ELSE        
            BEGIN
                INSERT #Parse SELECT REPLACE(SUBSTRING(@Desc,@Start,@End-@Start),',','') AS fldDesc 
            END
        SET @Start = @End + 1
    END

SELECT * FROM #Parse

フォームを開くたびに、このデータセットはデータベースをチェックして、この複数値パラメーターの保存された文字列を探します。存在しない場合は、nullを返します。 onがある場合、コンマを解析し、各値の行を作成します。

次に、このデータセットとfldDescにデフォルト値ボックスが設定されます。できます! 1つまたは複数を選択すると、フォームが再度開かれたときに保存され、補充されます。

これがお役に立てば幸いです。私はしばらく検索しましたが、データベースに結合文字列を保存し、データセットで解析することについて言及していませんでした。

1
Scott

ほんのコメント-私は、Oracle 10gとの接続でIN句を機能させようとして、痛い目に遭いました。書き換えられたクエリが10gデータベースに正しく渡されるとは思わない。複数値を完全に削除する必要がありました。クエリは、(複数値パラメーターセレクターから)単一の値が選択された場合にのみデータを返します。 MSとOracleのドライバーを同じ結果で試しました。誰かがこれで成功したかどうか聞きたいです。

1
ScottLenart

また、次のコードをストアドプロシージャに追加することもできます。

set @s = char(39) + replace(@s, ',', char(39) + ',' + char(39)) + char(39)

(@sが複数値の文字列(「A、B、C」など)であると仮定)

1

私はこのサイトを初めて使用しますが、以前の回答にコメントする方法を理解できませんでした。また、ジェフの投稿に賛成票を投じることもできませんでした。いずれかの方法...

すばらしい投稿とその後の微調整がどのように機能するかはわかりますが、データベースへの読み取りアクセス権しか持っていないため、UDF、SP、またはビューベースのソリューションは機能しません。エドハーパーのソリューションは、VenkateswarluAvulaのコメントを除き、コンマ区切りの文字列をパラメーターとしてWHERE IN句に渡すことはできず、必要に応じて機能することを期待できるという点を除いて、見栄えが良かったです。しかし、Oracle 10gに対するジェフのソリューションはそのギャップを埋めます。 Russell Christopherのブログ投稿でこれらをまとめます http://blogs.msdn.com/b/bimusings/archive/2007/05/07/how-do-you-set-select-all-as- the-default-for-multi-value-parameters-in-reporting-services.aspx と私は私の解決策を持っています:

使用可能な値のソース(おそらくデータセット)を使用して、複数選択パラメーターMYPARAMETERを作成します。私の場合、複数選択は多数のTEXTエントリからのものでしたが、他のタイプでも動作するように調整することで確信しています。すべて選択をデフォルトの位置にする場合は、同じソースをデフォルトとして設定します。これにより、ユーザーインターフェイスが提供されますが、作成されるパラメーターは、SQLに渡されるパラメーターではありません。

SQL、およびジェフのWHERE IN(@MYPARAMETER)問題の解決策に進んで、私はすべての問題を抱えています。1つの値(「Charge」)が他の値の1つ(「Non Charge」 )、CHARINDEXが偽陽性を見つける可能性があることを意味します。前後で区切り値のパラメーターを検索する必要がありました。これは、コンマ区切りリストにも先頭と末尾のコンマが含まれていることを確認する必要があることを意味します。そして、これは私のSQLスニペットです。

where ...
and CHARINDEX(',' + pitran.LINEPROPERTYID + ',', @MYPARAMETER_LIST) > 0

真ん中のビットは、次のように別のパラメーターを作成することです(開発中ではなく、実動では非表示)。

  • MYPARAMETER_LISTの名前
  • テキストの種類
  • ="," + join(Parameters!MYPARAMETER.Value,",") + ","の使用可能な単一の値と、
    は重要ではありません(表示されないため)。
  • まったく同じデフォルト値
  • 念のため、両方のパラメーターの[詳細設定]プロパティで[常に更新]を設定します

SQLに渡されるのはこのパラメーターであり、これはたまたま検索可能な文字列ですが、SQLはテキストの一部と同様に処理します。

これらの回答の断片をまとめることで、誰かが探しているものを見つけるのに役立つことを願っています。

1
Mark Belshaw

これは、一連の別個の文字列(たとえば、「START」、「END」、「ERROR」、「SUCCESS」)で機能しました

1)レポートパラメーター(@log_statusなど)を定義し、[複数の値を許可する]をオンにします
enter image description here

2)データセットを定義する
3)dataset-propertiesウィンドウを開きます
3a)Query-Tabにクエリを入力します。

select * from your_table where (CHARINDEX(your_column, @log_status,0) > 0)

3b)パラメータタブにパラメータを入力します。
Parametername: @log_status ; Parametervalue: <<Expr>>
3c)Exprの場合、「fx」ボタンをクリックして次を入力します。

=join(Parameters!log_status.Value,",")

enter image description here

終わった! (それはエド・ハーパーのソリューションに似ていますが、これが私にとってうまくいかなかったと言って申し訳ありません)

1
cjonas
  1. レポート内のリストのデータセットを作成します
  2. パラメーターを右クリックして、使用可能な値を選択します
  3. 新しく作成されたデータセットをデータセットとして選択
  4. 値フィールドとしてストアドプロシージャに渡す値を追加します
  5. パラメーターの説明をラベルフィールドに追加します(パラメーターがcustomerIDの場合、ラベルはCustomerName exになります)。
  6. 最後に、ストアドプロシージャに次のコードを追加します

@paramName AS NVARCHAR(500)を宣言し、

IF RIGHT(@paramName、1)= '、' BEGIN SET @paramName = LEFT((@ paramName、LEN((@ paramName)-1)END

過去に、ストアドプロシージャと関数を使用して、レポートサービスのSQL Serverクエリで複数年を選択することに頼りました。 Ed Harperによって提案されたように、クエリパラメーター値でJoin式を使用しても、whereステートメントのSQL IN句では機能しません。私の解決策は、パラメータJoin式とともにwhere句で次を使用することでした:and charindex(cast(Schl.Invt_Yr as char(4))、@Invt_Yr)> 0

0
J Steen

これは私に最適です:

WHERE CHARINDEX(CONVERT(nvarchar, CustNum), @CustNum) > 0
0
user3688168

MSSQL 2016-互換性レベル130では、String_Split()を利用してSSRSからの結合パラメーターを解析できます。 SSRSのクエリからパラメーターを設定し、そのパラメーターをストアドプロシージャまたはSSRS共有データセットに渡したいとします。

  1. SSRSレポートに2つのデータセットを追加します。1つはパラメーターに表示する値とラベルのリストを返し、もう1つはフィルターする実際のデータを含みます。これらの各データセットは、ストアドプロシージャ、共有データセット、または埋め込みクエリになります。
  2. フィルター処理するデータセットにないパラメーターをSSRSで作成します。 Customerと呼びましょう
  3. Customer paramを設定して複数の値を許可し、クエリから表示するデータセット、ラベル、および値でAvailable Valuesタブを設定します。
  4. フィルターするデータセットを右クリックして、ストアドプロシージャでIS定義されたパラメーターを追加します。 CustomerListと呼びましょう。
  5. このパラメーターの値フィールドの横にある式ボタンをクリックして、Join(Parameters!Customer.Value, ",")を実行します
  6. ストアドプロシージャまたは共有データセットで、string_splitを使用して、カンマ区切りの@CustomerList paramを配列に分割します:Customer.CustID in (select value from string_split(@CustomerList, ',') where value = Customer.CustID)
0

Oracleのソリューションが必要でしたが、DB> = 10gのレポートのクエリ内でこれが機能することがわかりました。

select * from where(select regexp_substr(、 '[^、] +'、1、level)from dual connect by regexp_substr(、 '[^、] +'、1、level)is not null);

ソース https://blogs.Oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement

0
Aaron

クエリ文字列を介して複数の値をRSに渡したい場合は、各値に対してレポートパラメーターを繰り返すだけです。

例えば; COLSというRS列があり、この列には1つ以上の値が必要です。

&rp:COLS=1&rp:COLS=1&rp:COLS=5 etc..
0
Gerry