it-swarm.com.de

Übergeben mehrerer Werte für einen einzelnen Parameter in Reporting Services

Ich habe mehrere Multi-Select-Parameter in meinem Bericht. Ich versuche einen Weg zu finden, um mehrere Werte für einen einzelnen Parameter in der Web-Abfragezeichenfolge zu übergeben. Wenn ich einen einzelnen Wert übergebe, funktioniert es gut.

Der Bericht wird gut ausgeführt, indem mehrere Optionen für einen einzelnen Parameter ausgewählt werden. Mein Problem liegt in der Web-Abfragezeichenfolge.

Obwohl die Lösung von John Sansom funktioniert, gibt es eine andere Möglichkeit, dies zu tun, ohne eine möglicherweise ineffiziente UDF .. verwenden zu müssen 

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

In Ihrer Abfrage können Sie den Wert dann wie folgt referenzieren:

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

Dies ist was ich benutze, wenn ich einen Multi-Select-Parameter an einen anderen Multi-Select-Parameter übergeben möchte.

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

Dies ist eine der schlecht unterstützten Funktionen in SQL Reporting Services.

Was Sie tun müssen, ist, alle ausgewählten Elemente als eine einzige Zeichenfolge an Ihre gespeicherte Prozedur zu übergeben. Jedes Element innerhalb der Zeichenfolge wird durch ein Komma getrennt.

Was ich dann mache, ist der String mit einer Funktion zu teilen, die den bereitgestellten String als Tabelle zurückgibt. Siehe unten.

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

Sie können die Ergebnisse dann in der where-Klausel Ihrer Hauptabfrage wie folgt referenzieren:

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

Ich hoffe, Sie finden diese Lösung nützlich. Bitte zögern Sie nicht, Ihre Fragen zu stellen.

Prost, John

21
John Sansom

John Sansom und Ed Harper haben großartige Lösungen. Im Umgang mit ID-Feldern (d. H. Ganzzahlen) konnte ich sie jedoch nicht zur Arbeit bringen. Ich habe die aufgeteilte Funktion geändert, um die Werte als Ganzzahlen zu CAST, damit die Tabelle mit Primärschlüsselspalten verknüpft wird. Ich habe auch den Code kommentiert und eine Spalte für die Reihenfolge hinzugefügt, falls die Reihenfolge der Trennzeichen signifikant war.

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

Verwenden Sie diese Funktion wie zuvor beschrieben mit:

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

Ich bin auf ein Problem mit dem ansonsten wundervollen fn_MVParam gestoßen.

Ich habe eine Zeile hinzugefügt, um das Problem zu beheben.

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

Meine Version des Fn verwendet auch Varchar anstelle von Nvarchar.

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

Orakel:

Die "IN" -Phrase (Ed's Solution) funktioniert nicht bei einer Oracle-Verbindung (mindestens Version 10). Allerdings fand diese einfache Problemumgehung das. Verwenden Sie die Registerkarte des Datensatzparameters, um aus dem Parameter mit mehreren Werten eine CSV zu erstellen:

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

Verwenden Sie dann in der WHERE-Klausel Ihrer SQL-Anweisung die instring-Funktion, um nach einer Übereinstimmung zu suchen.

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

Änderung der großen John-Lösung, lösen Sie:

  • Fehler "2 Anführungszeichen"
  • leerzeichen nach einem Stück im Parameter

    
    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

Multiplizierte Textwerte würden in der Abfrage mit einfachen Anführungszeichen um jeden verwendeten Join (Parameter! Customer.Value, "','") enden. Nach ".Value" sind das also Komma, Anführungszeichen, einfache Anführungszeichen, Komma, einfache Anführungszeichen, doppelte Anführungszeichen, schließende Klammern. einfach :)

1
RichardBSmith

Die untenstehende Lösung hat für mich funktioniert.

  1. Klicken Sie auf der Registerkarte "Parameter" der Eigenschaften Ihres Datensatzes auf das Ausdruckssymbol (! http://chittagongit.com//images/fx-icon/fx-icon-16.jpg [fx-Symbol]) neben dem Parameter, den Sie angeben müssen durch Kommas getrennte Einträge zulassen. 

  2. Verwenden Sie im angezeigten Ausdrucksfenster die Funktion Teilen (Allgemeine Funktionen -> Text). Beispiel unten gezeigt:

= Split (Parameter! ParameterName.Value, ",")

1
sherebry

Es ist wahrscheinlich einfacher, die Multi-Werte zuerst zu einer Tabelle hinzuzufügen, und Sie können dann beitreten oder was auch immer Sie möchten (sogar mit Platzhaltern) oder die Daten für eine spätere Verwendung in einer anderen Tabelle speichern (oder sogar die Werte einer anderen Tabelle hinzufügen). .

Setze den Parameterwert per Ausdruck in der Datenmenge:

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

Die Abfrage selbst:

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

INSERT INTO @Table EXEC sp_executeSQL @SearchValue 

Platzhalterbeispiel:

SELECT * FROM YOUR_TABLE yt 

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

Ich würde gerne einen Weg finden, um dies ohne dynamisches SQL zu tun, aber ich denke nicht, dass es funktionieren wird, da SSRS die Parameter an die eigentliche Abfrage übergibt. Wenn jemand es besser weiß, lass es mich wissen.

1
jon

Es geht darum, die Join-Funktion zu verwenden, um einen mehrwertigen Parameter zu speichern und später genau dieselbe Auswahl aus der Datenbank wiederherzustellen.

Ich habe gerade einen Bericht fertiggestellt, der die Anforderung hatte, dass die Parameter gespeichert werden müssen. Wenn der Bericht erneut geöffnet wird (der Bericht wird an einen OrderID-Parameter übergeben), müssen die zuvor vom Benutzer ausgewählten Werte erneut ausgewählt werden.

Der Bericht verwendete ein halbes Dutzend Parameter, jeder hatte seinen eigenen Datensatz und eine Dropdown-Liste. Die Parameter waren von den vorherigen Parametern abhängig, um den Umfang der endgültigen Auswahl einzugrenzen. Wenn der Bericht "angesehen" wurde, wurde eine gespeicherte Prozedur aufgerufen, um sie aufzufüllen.

Die gespeicherte Prozedur hat jeden der übergebenen Parameter aus dem Bericht erhalten. Es hat eine Speichertabelle in der Datenbank geprüft, um zu sehen, ob Parameter für diese OrderID gespeichert wurden. Wenn nicht, werden alle Parameter gespeichert. Wenn ja, wurden alle Parameter für diese Reihenfolge aktualisiert (dies ist der Fall, wenn der Benutzer später seine Meinung ändert). 

Wenn der Bericht ausgeführt wird, gibt es eine Dataset dsParameters. Hierbei handelt es sich um SQL-Text, der ausgegeben wird und die einzelne Zeile für diese orderID auswählt, falls vorhanden. Jeder Parameter im Bericht erhält seinen Standardwert aus dieser Datenmenge und seine Auswahlliste aus einer Datenmenge, die diesem Parameter zugeordnet ist.

Ich habe Probleme mit dem Parameter für die Mehrfachauswahl. Ich verwendete einen join-Befehl (@Value, ",") in der Parameterliste der Haupt-Datasets und übergab eine durch Kommas getrennte Zeichenfolge an die gespeicherte Prozedur. Aber wie kann man es wiederherstellen? Die durch Kommas getrennte Zeichenfolge kann nicht in das Feld mit den Standardwerten des Parameters zurückgegeben werden.

Ich musste ein anderes Dataset erstellen, um den Parameter auf ähnliche Weise zu teilen, wie Sie es sich vorstellen. Es sieht aus wie das:

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,@[email protected]),',','') AS fldDesc 
            END
        SET @Start = @End + 1
    END

SELECT * FROM #Parse

Bei jedem Öffnen des Formulars überprüft diese Datenmenge die Datenbank auf eine gespeicherte Zeichenfolge für diesen mehrwertigen Parameter. Wenn keine vorhanden ist, wird null zurückgegeben. Ist diese Option aktiviert, werden die Kommas analysiert und für jeden Wert eine Zeile erstellt.

Dann wird das Feld mit den Standardwerten auf diese Datenmenge und fldDesc gesetzt. Es klappt! Wenn ich einen oder mehrere auswähle, werden sie gespeichert und beim erneuten Öffnen des Formulars wieder aufgefüllt.

Ich hoffe das hilft. Ich suchte eine Weile und fand keine Erwähnung, das Speichern der Join-Zeichenfolge in einer Datenbank zu speichern und sie dann in einem Dataset auszuwerten.

1
Scott

Nur ein Kommentar - Ich bin in eine Welt voller Schmerzen geraten, als ich versuchte, eine IN-Klausel in Verbindung mit Oracle 10g zu verwenden. Ich glaube nicht, dass die umgeschriebene Abfrage korrekt an eine 10-GB-Db übertragen werden kann. Ich musste den Mehrfachwert komplett fallen lassen. Die Abfrage würde nur dann Daten liefern, wenn ein einzelner Wert (aus dem Mehrfachwert-Parameterselektor) ausgewählt wurde. Ich habe die MS- und Oracle-Treiber mit den gleichen Ergebnissen getestet. Ich würde gerne hören, wenn jemand damit Erfolg hatte.

1
ScottLenart

Sie können diesen Code auch in Ihre gespeicherte Prozedur einfügen:

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

(Angenommen, @s ist eine mehrwertige Zeichenfolge (wie "A, B, C"))

1

Ich bin neu auf der Website und konnte nicht herausfinden, wie ich eine vorherige Antwort kommentieren sollte. Dies ist meiner Meinung nach. Ich konnte auch nicht Jeff's Posten wählen, was meiner Meinung nach meine Antwort gab. Sowieso...

Während ich sehen kann, wie einige der großartigen Beiträge und die nachfolgenden Anpassungen funktionieren, habe ich nur Lesezugriff auf die Datenbank. Daher funktionieren für mich keine UDF, SP oder ansichtsbasierte Lösungen. Die Lösung von Ed Harper sah also gut aus, abgesehen von VenkateswarluAvulas Kommentar, dass Sie eine durch Kommas getrennte Zeichenfolge nicht als Parameter in eine WHERE IN-Klausel übergeben können und erwarten können, dass sie nach Bedarf funktioniert. Jeffs Lösung für das Oracle 10g schließt diese Lücke. Die habe ich mit dem Blog-Beitrag von Russell Christopher zusammengestellt unter 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 und ich habe meine Lösung:

Erstellen Sie Ihren Multi-Select-Parameter MYPARAMETER mit einer beliebigen Quelle verfügbarer Werte (wahrscheinlich eines Datensatzes). In meinem Fall bestand die Mehrfachauswahl aus einer Reihe von TEXT-Einträgen, aber ich bin mir sicher, dass sie mit einigen Optimierungen mit anderen Typen funktionieren würde. Wenn Sie "Alle auswählen" als Standardposition festlegen möchten, legen Sie dieselbe Quelle als Standardposition fest. Dadurch erhalten Sie Ihre Benutzeroberfläche, aber der erstellte Parameter ist nicht der an meine SQL übergebene Parameter. 

Ich habe die SQL-Lösung und Jeffs Lösung für das WHERE IN (@MYPARAMETER) -Problem übersprungen. Ich habe ein eigenes Problem, da einer der Werte ('Charge') in einem der anderen Werte ('Non Charge') erscheint. ), was bedeutet, dass der CHARINDEX einen falsch positiven Wert finden kann. Ich musste vor und nach dem Parameter nach dem begrenzten Wert suchen. Das heißt, ich muss sicherstellen, dass die durch Kommas getrennte Liste auch ein führendes und ein nachfolgendes Komma enthält. Und das ist mein SQL-Snippet:

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

Das Mittel in der Mitte besteht darin, einen anderen Parameter zu erstellen (in der Produktion verborgen, aber nicht während der Entwicklung) mit:

  • Ein Name von MYPARAMETER_LIST
  • Eine Art von Text 
  • Ein einzelner verfügbarer Wert von ="," + join(Parameters!MYPARAMETER.Value,",") + "," und eine Bezeichnung dafür
    spielt keine Rolle (da es nicht angezeigt wird).
  • Ein Standardwert ist genau gleich
  • Um sicherzugehen, habe ich in den beiden Parametern 'Advancedproperties' Always Refresh eingestellt

Dieser Parameter wird an SQL übergeben, was zufällig eine durchsuchbare Zeichenfolge ist, die jedoch von SQL wie ein beliebiger Text behandelt wird.

Ich hoffe, diese Fragmente der Antworten zusammenzusetzen, hilft jemandem, das zu finden, wonach er sucht.

1
Mark Belshaw

dies funktionierte für einen bestimmten Satz von Zeichenketten (z. B. "START", "END", "ERROR", "SUCCESS").

1) Definieren Sie einen Bericht-Parameter (z. B. @log_status) und markieren Sie "Mehrere Werte zulassen".
 enter image description here

2) einen Datensatz definieren
3) Öffnen Sie das Fenster mit den Dataset-Eigenschaften
3a) Geben Sie Ihre Abfrage in das Abfrage-Tab ein: z.

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

3b) Geben Sie im Parameter-Tab Ihren Parameter ein, z.
Parametername: @log_status ; Parametervalue: <<Expr>> 
3c) Klicken Sie für den Ausdruck auf den "fx" -Button und geben Sie Folgendes ein:

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

 enter image description here

fertig! (Es ist der Lösung von Ed Harper ähnlich, aber es tut mir leid, dass dies für mich nicht funktioniert hat.)

1
cjonas

Das funktioniert gut für mich:

WHERE CHARINDEX(CONVERT(nvarchar, CustNum), @CustNum) > 0
1
user3688168
  1. Erstellen Sie das Dataset für die Liste im Bericht
  2. Klicken Sie mit der rechten Maustaste auf den Parameter und wählen Sie die verfügbaren Werte aus
  3. Wählen Sie neu erstellte Datenmenge als Datenmenge aus
  4. Fügen Sie den Wert der gespeicherten Prozedur als Wertfeld hinzu 
  5. Fügen Sie die Beschreibung des Parameters zum Beschriftungsfeld hinzu (Wenn der Parameter customerID ist, könnte label als CustomerName angegeben werden.)
  6. Fügen Sie Ihrer gespeicherten Prozedur schließlich folgenden Code hinzu

@paramName als NVARCHAR (500) deklarieren,

WENN RECHTS (@paramName, 1) = ',' BEGIN SET @paramName = LEFT ((@ paramName, LEN ((@ paramName) -1) END

In der Vergangenheit habe ich auf gespeicherte Prozeduren und eine Funktion zurückgegriffen, um mehrere Jahre in einer SQL Server-Abfrage für Berichterstellungsdienste auszuwählen. Die Verwendung des Join-Ausdrucks im Abfrageparameterwert, wie von Ed Harper vorgeschlagen, funktioniert immer noch nicht mit einer SQL-IN-Klausel in der where-Anweisung. Meine Lösung bestand darin, zusammen mit dem Parameter Join-Ausdruck Folgendes in der where-Klausel zu verwenden: und charindex (cast (Schl.Invt_Yr als char (4)), @Invt_Yr)> 0

0
J Steen

Ab MSSQL 2016 - mit Kompatibilitätsstufe 130 können Sie String_Split() verwenden, um Ihren verknüpften Parameter aus SSRS zu analysieren. Angenommen, Sie möchten einen Parameter aus einer Abfrage in SSRS füllen und diesen Parameter dann an einen gespeicherten Prozess oder ein gemeinsam genutztes SSRS-Dataset übergeben:

  1. Fügen Sie Ihrem SSRS-Bericht zwei Datensätze hinzu, einen mit einer Liste der Werte und Bezeichnungen, die in Ihrem Parameter angezeigt werden sollen, und einen mit den tatsächlichen Daten, die Sie filtern möchten. Bei jedem dieser Datasets kann es sich um einen gespeicherten Prozess, ein freigegebenes Dataset oder eine eingebettete Abfrage handeln.
  2. Erstellen Sie in SSRS einen Parameter, der NICHT in dem Dataset enthalten ist, das Sie filtern möchten. Nennen wir es Customer
  3. Legen Sie Customer param fest, um mehrere Werte zuzulassen, und richten Sie die Registerkarte Available Values mit dem Datensatz, den Bezeichnungen und den Werten ein, die Sie in der Abfrage anzeigen möchten.
  4. Klicken Sie mit der rechten Maustaste auf das Dataset, das Sie filtern möchten, und fügen Sie einen Parameter hinzu, den IS in der gespeicherten Prozedur definiert hat. Nennen wir es CustomerList.
  5. Klicken Sie auf die Ausdrucksschaltfläche neben dem Wertefeld für diesen Parameter und führen Sie Join(Parameters!Customer.Value, ",") aus.
  6. Verwenden Sie in Ihrem gespeicherten Prozess oder gemeinsam genutzten Dataset string_split, um den durch Kommas getrennten Parameter @CustomerList in ein Array zu unterteilen: Customer.CustID in (select value from string_split(@CustomerList, ',') where value = Customer.CustID)
0

Ich brauchte eine Lösung für Oracle und fand heraus, dass dies in meiner Abfrage für meinen Bericht für DB> = 10g für mich funktionierte.

select * from where in ( select regexp_substr (, '[^,] +', 1, level) aus dual connect durch regexp_substr (, '[^,] +', 1, level) ist nicht null );

source https://blogs.Oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement

0
Aaron

Wenn Sie mehrere Werte über eine Abfragezeichenfolge an RS übergeben möchten, müssen Sie lediglich den Berichtsparameter für jeden Wert wiederholen. 

Zum Beispiel; Ich habe eine RS-Spalte namens COLS und diese Spalte erwartet einen oder mehrere Werte. 

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