Transmission de plusieurs valeurs pour un seul paramètre dans Reporting Services

J'ai plusieurs paramètres Multi-Select dans mon rapport. J'essaie de trouver un moyen de passer plusieurs valeurs pour un seul paramètre dans la chaîne de requête web? Si je passe une seule valeur, cela fonctionne bien.

Le rapport s'exécute correctement en sélectionnant plusieurs choix pour un seul paramètre. Mon problème réside dans la chaîne de requête web.

63
demandé sur Ned Batchelder 2009-02-04 19:24:50

20 réponses

Bien que la solution de John Sansom fonctionne, il existe une autre façon de le faire, sans avoir à utiliser un UDF scalaire potentiellement inefficace. Dans le rapport SSRS, dans l'onglet Paramètres de la définition de requête, définissez la valeur du paramètre sur

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

Dans votre requête, vous pouvez alors référencer la valeur comme suit:

where yourColumn in (@<your param name>)
90
répondu Ed Harper 2009-02-06 08:42:32

C'est ce que j'utilise lors du passage d'un paramètre multi-select à un autre paramètre multi-select.

=SPLIT(JOIN(Parameters!<your param name>.Value,","),",")
38
répondu Mhd. Yasseen 2013-04-10 11:56:15

C'est l'une des fonctionnalités mal prises en charge dans SQL Reporting Services.

Ce que vous devez faire est de passer tous vos éléments sélectionnés en une seule chaîne à votre procédure stockée. Chaque élément de la chaîne sera séparé par une virgule.

Ce que je fais ensuite est de diviser la chaîne en utilisant une fonction qui renvoie la chaîne fournie en tant que table. Voir ci-dessous.

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

Vous pouvez ensuite référencer les résultats dans la clause where de votre requête principale comme suit:

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

J'espère que cela vous trouvez cette solution utile. N'hésitez pas à poser toutes les questions que vous pourriez avoir.

Acclamations,Jean -

20
répondu John Sansom 2011-09-02 12:23:58

John Sansom et Ed Harper ont d'excellentes solutions. Cependant, je n'ai pas pu les faire fonctionner lors du traitement des champs ID (C'est-à-dire des entiers). J'ai modifié la fonction split ci-dessous pour convertir les valeurs en entiers de sorte que la table se joindra aux colonnes de clé primaire. J'ai également commenté le code et ajouté une colonne pour l'ordre, au cas où l'ordre de liste délimité était significatif.

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

Utiliser cette fonction comme indiqué précédemment avec:

WHERE id IN (SELECT Number FROM dbo.fn_SplitInt(@sParameterString,','))
7
répondu CodeGrue 2011-09-02 12:22:47

ORACLE:

La phrase " IN " (Solution D'Ed) ne fonctionnera pas avec une connexion Oracle (au moins version 10). Cependant, trouvé ce travail-autour simple qui fait. À l'aide de l'onglet du paramètre de l'ensemble de données, transformez le paramètre multi-valeurs en CSV:

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

Ensuite, dans la clause WHERE de votre instruction SQL, utilisez la fonction instring pour vérifier une correspondance.

    INSTR(:name, TABLE.FILENAME) > 0
3
répondu Jeff 2009-11-02 22:21:35

J'ai rencontré un problème avec le fn_MVParam autrement merveilleux. SSRS 2005 a envoyé des données avec une apostrophe en 2 guillemets.

J'ai ajouté une ligne pour résoudre ce problème.

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

MA version du fn utilise également varchar au lieu de 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
3
répondu Bob Amy 2012-11-28 13:21:43

Modification de la solution Great John, résoudre:

  • Erreur "2 guillemets"
  • Espace après une pièce dans le paramètre

    
    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
    
    
2
répondu grum 2012-10-08 10:24:37

Juste un commentaire-j'ai rencontré un monde de mal à essayer de faire fonctionner une clause IN dans une connexion à Oracle 10g. Je ne pense pas que la requête réécrite puisse être correctement transmise à une base de données 10g. J'ai dû abandonner complètement la multi-valeur. La requête ne retournerait des données que lorsqu'une seule valeur (à partir du sélecteur de paramètres multi-valeurs) était choisie. J'ai essayé les pilotes MS et Oracle avec les mêmes résultats. J'aimerais savoir si quelqu'un a eu du succès avec cette.

1
répondu ScottLenart 2009-02-07 17:33:52
  1. crée l'ensemble de données pour la liste dans le rapport
  2. cliquez avec le bouton droit sur le paramètre et sélectionnez les valeurs disponibles
  3. Sélectionnez l'ensemble de données nouvellement créé en tant qu'ensemble de données
  4. Ajouter la valeur passant à la procédure stockée en tant que champ de valeur
  5. Ajoutez la description du paramètre au champ label (si le paramètre est customerID alors label pourrait être CustomerName ex.)
  6. Enfin, ajoutez le code suivant à votre procédure stockée

Déclare @paramName comme NVARCHAR (500),

Si droit (@paramName, 1)=',' COMMENCER SET @paramName = LEFT((@paramName, len ((@paramName)-1) Fin

1
répondu Nilanka Sooriyabandara 2013-06-27 14:06:00

Cela fonctionne très bien pour moi:

WHERE CHARINDEX(CONVERT(nvarchar, CustNum), @CustNum) > 0
1
répondu user3688168 2014-05-29 15:48:41

Il serait probablement plus facile d'ajouter les valeurs multiples à une table en premier, puis vous pouvez joindre ou tout ce que vous voulez (même avec des caractères génériques) ou enregistrer les données dans une autre table pour une utilisation ultérieure (ou même ajouter les valeurs à une autre table).

Définissez la valeur du paramètre via l'expression dans l'ensemble de données:

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

La requête elle-même:

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

INSERT INTO @Table EXEC sp_executeSQL @SearchValue 

Exemple Générique:

SELECT * FROM YOUR_TABLE yt 

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

J'aimerais trouver un moyen de le faire sans SQL dynamique mais je ne pense pas cela fonctionnera en raison de la façon dont SSRS transmet les paramètres à la requête réelle. Si quelqu'un sait mieux, faites-le moi savoir.

1
répondu jon 2016-08-05 18:42:05

Cela a fonctionné pour un ensemble distinct de chaînes (par exemple "START", "END", "ERROR", "SUCCESS" )

1) Définissez un paramètre de rapport (par exemple @log_status) et cochez "Autoriser plusieurs valeurs"
entrez la description de l'image ici

2) définir un ensemble de données
3) Ouvrez la fenêtre dataset-properties
3a) dans L'onglet Requête, entrez votre requête: par exemple

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

3b) dans L'onglet Paramètres, entrez votre paramètre, par exemple
Parametername: @log_status ; Parametervalue: <<Expr>>
3c) pour L'Expr, cliquez sur le bouton " fx " et entrez:

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

entrez la description de l'image ici

Fini! ( c'est similaire à la solution D'Ed Harper, mais désolé de dire que cela n'a pas fonctionné pour moi)

1
répondu cjonas 2018-05-25 10:57:07

Si vous voulez passer plusieurs valeurs à RS via une chaîne de requête, il vous suffit de répéter le paramètre report pour chaque valeur.

Par exemple; j'ai une colonne RS appelée COLS et cette colonne attend une ou plusieurs valeurs.

&rp:COLS=1&rp:COLS=1&rp:COLS=5 etc..
0
répondu Gerry 2012-10-26 21:08:58

Ce que vous pouvez faire est d'ajouter ce code dans votre procédure stockée:

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

(en supposant que @s est une chaîne à valeurs multiples (comme "A, B, C"))

0
répondu Wilfred van Dijk 2012-12-04 22:53:50

Je suis nouveau sur le site, et je ne pouvais pas comprendre comment commenter une réponse précédente, ce qui est ce que je pense que cela devrait être. Je ne pouvais pas non plus voter le post de Jeff, ce qui, je crois, m'a donné ma réponse. De toute façon...

Bien que je puisse voir comment certains des grands messages, et les modifications ultérieures, fonctionnent, Je n'ai qu'un accès en lecture à la base de données, donc aucune solution UDF, SP ou vue ne fonctionne pour moi. Donc, la solution D'Ed Harper avait l'air bien, sauf pour le commentaire de VenkateswarluAvula que vous ne pouvez pas passer une virgule séparée string en tant que paramètre dans une clause WHERE IN et attendez-vous à ce qu'il fonctionne comme vous le souhaitez. Mais la solution de Jeff à L'ORACLE 10g comble cette lacune. Je les ai mis ensemble avec le blog de 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 et j'ai ma solution:

Créez votre paramètre multi-sélection MYPARAMETER en utilisant n'importe quelle source de valeurs disponibles (probablement un dataset). Dans mon cas, la multi-sélection était à partir d'un tas d'entrées de texte, mais je suis sûr qu'avec quelques ajustements, cela fonctionnerait avec d'autres types. Si vous voulez que tout sélectionner soit la position par défaut, définissez la même source que la position par défaut. Cela vous donne votre interface utilisateur, mais le paramètre créé n'est pas le paramètre passé à mon SQL.

Sauter à L'avance au SQL, et la solution de Jeff au problème WHERE IN (@MYPARAMETER), j'ai un problème tout à moi, en ce que 1 des valeurs ('Charge') apparaît dans l'une des autres valeurs ('Non Charge'), ce qui signifie que le CHARINDEX pourrait trouver un faux positif. J'avais besoin de rechercher le paramètre pour la valeur délimitée à la fois avant et après. Cela signifie que je dois m'assurer que la liste séparée par des virgules a également une virgule de début et de fin. Et voici mon extrait SQL:

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

Le bit au milieu consiste à créer un autre paramètre (caché en production, mais pas en développement) avec:

  • un nom de MYPARAMETER_LIST
  • un type de texte
  • Une seule valeur disponible de ="," + join(Parameters!MYPARAMETER.Value,",") + "," et un label
    n'a pas vraiment d'importance (car il ne sera pas affichée).
  • une valeur par défaut exactement la même
  • juste pour être sûr, je mets toujours rafraîchir dans les deux paramètres avancés propriétés

C'est ce paramètre qui est passé à SQL, qui se trouve être une chaîne consultable mais que SQL gère comme n'importe quel morceau de texte.

J'espère que mettre ces fragments de réponses ensemble aide quelqu'un trouver ce qu'ils recherchent.

0
répondu Mark Belshaw 2013-02-14 19:41:53

Dans le passé, j'ai eu recours à des procédures stockées et à une fonction pour sélectionner plusieurs années dans une requête SQL Server pour les services de reporting. L'utilisation de L'expression de jointure dans la valeur du paramètre de requête comme suggéré par Ed Harper, ne fonctionnerait toujours pas avec une clause SQL IN dans l'instruction where. Ma résolution était d'utiliser ce qui suit dans la clause where avec l'expression de jointure de paramètre: et charindex (cast (Schl.Invt_Yr comme char (4)), @ Invt_Yr) > 0

0
répondu J Steen 2013-03-20 19:25:30

Il s'agit d'utiliser la fonction join pour enregistrer un paramètre à plusieurs valeurs, puis de restaurer les mêmes sélections de la base de données ultérieurement.

Je viens de terminer un rapport qui avait des exigences que les paramètres doivent être enregistrés, et lorsque le rapport est ouvert à nouveau (le rapport est passé un paramètre OrderID), les valeurs précédemment choisies par l'utilisateur doivent être à nouveau sélectionnées.

Le rapport a utilisé une demi-douzaine de paramètres, chacun ayant son propre ensemble de données et la chute résultante en bas de la liste. Les paramètres dépendaient des paramètres précédents pour réduire la portée de la sélection finale, et lorsque le rapport a été "consulté" une procédure stockée a été appelée pour remplir.

La procédure stockée a reçu chacun des paramètres qui lui ont été transmis à partir du rapport. Il a vérifié une table de stockage dans la base de données pour voir si des paramètres ont été enregistrés pour cet OrderID. Sinon, il a enregistré tous les paramètres. Si c'est le cas, il a mis à jour tous les paramètres de cet ordre (c'est le cas où l'utilisateur de modifier leur l'esprit plus tard).

Lorsque le rapport s'exécute, il y a un jeu de données dsParameters qui est du texte SQL qui sort et sélectionne la seule ligne pour cet orderID s'il y en a une. Chacun des paramètres du rapport obtient sa valeur par défaut à partir de cet ensemble de données, et sa liste de sélection à partir d'un ensemble de données dédié à ce paramètre.

J'ai eu des problèmes avec le paramètre multi-select. J'ai utilisé une commande join(@Value,",") dans la liste des paramètres du jeu de données principal, en passant à la procédure stockée une chaîne délimitée par des virgules. Mais comment le restaurer? Vous ne pouvez pas renvoyer la chaîne délimitée par des virgules à la zone Valeurs par défaut du paramètre.

J'ai dû créer un autre ensemble de données pour diviser le paramètre, d'une manière similaire à ce dont vous parlez. Il ressemble à ceci:

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

Chaque fois que le formulaire s'ouvre, cet ensemble de données vérifie la base de données pour une chaîne enregistrée pour ce paramètre à valeurs multiples. S'il n'y en a pas, il renvoie null. Si il est sur, il analyse les virgules et crée une ligne pour chacune des valeurs.

Ensuite, la zone Valeurs par défaut est définie sur cet ensemble de données et fldDesc. Il fonctionne! Quand je choisis un ou plusieurs, ils sauvegardent et réapprovisionnent lorsque le formulaire est ouvert à nouveau.

J'espère que cela aide. J'ai cherché pendant un moment et n'ai trouvé aucune mention de l'enregistrement de la chaîne de jointure dans une base de données, puis de son analyse dans un ensemble de données.

0
répondu Scott 2013-05-04 00:01:15

Donc multiplier les valeurs de texte finirait dans la requête avec des guillemets simples autour de chaque j'ai utilisé =join (paramètres!Client.Valeur,"','"). Donc après".De la valeur", c'est-virgule, les guillemets, apostrophes, des virgules, apostrophes, guillemets, à proximité du support. simples :)

0
répondu RichardBSmith 2016-12-09 11:24:25

La solution ci-dessous a fonctionné pour moi.

  1. Dans l'onglet Paramètres des propriétés de votre jeu de données, cliquez sur l'icône expression (! http://chittagongit.com//images/fx-icon/fx-icon-16.jpg [symbole fx]) à côté du paramètre, vous devez autoriser l'entrée délimitée par des virgules pour.

  2. Dans la fenêtre d'expression qui apparaît, utilisez la fonction Split (fonctions communes - > texte). Exemple ci-dessous:

=Split(Paramètres!ParameterName.Valeur,",")

0
répondu sherebry 2018-06-12 00:13:27

J'avais besoin d'une solution pour Oracle et j'ai trouvé que cela fonctionnait pour moi dans ma requête pour mon rapport pour DB > = 10g.

Sélectionnez * d'où dans ( sélectionner regexp_substr(,'[^,]+', 1, niveau) de double se connecter par regexp_substr(, '[^,]+', 1, niveau) n'est pas null );

Source https://blogs.oracle.com/aramamoo/entry/how_to_split_comma_separated_string_and_pass_to_in_clause_of_select_statement

-1
répondu Aaron 2017-01-09 22:02:18