Paramètre SSRS multi-valeurs utilisant une procédure stockée
je travaille sur un rapport SSRS qui utilise une procédure stockée contenant quelques paramètres. J'ai des problèmes avec deux des paramètres parce que je veux avoir la possibilité de choisir plus d'un article.
Voici une version condensée de ce que j'ai:
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)
quand j'essaie d'exécuter la procédure stockée, Je ne renvoie des valeurs que si j'entre seulement 1 Valeur pour <!--2 et 1 Valeur @ReportProductFamilyID
. Si j'essaie d'entrer deux SalesGroupID
et/ou 2 ProductFamilyID
il ne se trompe pas, mais je renvoie rien.
-- 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'
Dans SSRS j'obtiens un message d'erreur qui dit:
syntaxe Incorrecte près de ','
Il semble que le ,
séparateur est inclus dans la chaîne au lieu d'un délimiteur
4 réponses
Vous avez besoin de trois choses:
dans les propriétés de l'ensemble de données SSRS, passez le paramètre multi-valeurs à la procédure stockée comme une chaîne délimitée par une virgule
=Join(Parameters!TerritoryMulti.Value, ",")
dans Sql Server, vous avez besoin d'une fonction table-value qui peut séparer une chaîne délimitée par une virgule en une mini table (par exemple voir ici)
dans la procédure stockée, avoir une clause où quelque chose comme ceci:
WHERE sometable.TerritoryID in (select Item from dbo.ufnSplit(@TerritoryMulti,','))
... où
ufnSplit
est votre fonction de division de l'étape 2.
(Plein étapes et du code dans mon blog 'SSRS multi-paramètres de valeur avec moins d'échouer'):
supposons que vous avez une liste de valeurs multiples @param1
Créer un autre Paramètre Interne sur votre rapport SSRS appelé @param2
et définissez la valeur par défaut:
=Join(Parameters!param1.value, 'XXX')
XXX
peut être n'importe quel délimiteur que vous voulez, sauf une virgule (voir ci-dessous)
Ensuite, vous pouvez passer @param2
à votre requête ou une procédure stockée.
si vous essayez de le faire d'une autre manière, cela causera l'échec de toute fonction de chaîne qui utilise des virgules pour séparer les arguments. (par exemple CHARINDEX, remplacer).
Par exemple Replace(@param2, ',', 'replacement')
ne fonctionne pas. Vous finirez avec des erreurs comme "Replace function requires 3 arguments".
finalement j'ai pu trouver une solution simple à ce problème. Ci-dessous, j'ai fourni toutes les (3) étapes que j'ai suivies.
j'espère que vous allez aimez :)
Étape 1-j'ai créé une table de température globale avec une colonne.
CREATE GLOBAL TEMPORARY TABLE TEMP_PARAM_TABLE(
COL_NAME VARCHAR2(255 BYTE)
) ON COMMIT PRESERVE ROWS NOCACHE;
Étape 2-dans la procédure de split, Je n'ai pas utilisé de tableau ou de datatable, j'ai directement chargé les valeurs de split dans ma table de température globale.
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;
/
Étape 3 - dans les paramètres de l'ensemble de données SSRS, j'ai utilisé
=Join(Parameters!A_COUNTRY.Value, ",")
Etape 4: Au début de votre procédure stockée exécute la procédure
Exec split_param(A_Country, ‘,’);
Étape 5: dans votre procédure stockée sql utiliser la condition comme ci-dessous.
Where country_name in (select * from TEMP_PARAM_TABLE)
quand SSRS passe le paramètre il est sous la forme: Param1,Param2,Param3.
dans la procédure, vous avez juste besoin de mettre des identificateurs autour de chaque paramètre. Et aussi des identificateurs autour de la valeur qui est retournée par l'ensemble de données. Dans mon cas, j'ai utilisé des points-virgule.
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 est transmis via SSRS.
l_multivalue_parameter lit le paramètre passé dans via SSRS et met des identificateurs autour de chaque valeur.
database_value_that_is_singular est la valeur retournée pour chaque enregistrement.
donc si 'Type1, Type2,Type3' est passé par SSRS:
i_multivalue_parameter est: Type1,Type2,Type3
l_multivalue_parameter est: ;Type1;Type2;Type3;
database_value_that_is_singular est: ;Type1; ou ;Type2; ou ;Type3;
Instr retournera une valeur supérieure à 0 si le paramètre correspond.
cela fonctionne même si chaque paramètre sont similaires. Par exemple:" Type A "et"Type AA". C'est-à-dire que "Type A" ne correspondra pas à "Type AA".