Comment puis-je passer et traiter un tableau de varchars en tant que parameters vers / dans un paramètre de procédure stockée SQL Server?

J'utilise une procédure stockée existante qui déclare ces parameters:

@Unit varchar(4000), @BegDate datetime, @EndDate datetime, @SortBy varchar(20) 

Le défi que je suis maintenant confronté est de venir avec une dérivation de cette procédure stockée qui prend un certain nombre de parameters @Unit, de 1..N

Comment puis je faire ça? S'agit-il de changer le paramètre @Unit en @Unit varchar (max), d'assigner des valeurs délimitées au paramètre, puis d'parsingr la valeur délimitée à partir de la procédure stockée?

IOW, dois-je faire quelque chose comme ça dans le proc stocké:

 @Unit varchar(max), @BegDate datetime, @EndDate datetime, @SortBy varchar(20) 

… ceci dans le code C #:

 ssortingng unit = unit1 +',' + unit2 +',' + unit3 // and on for however many units are being added . . . sqlCommand.Parameters.AddWithValue("@Unit", unit); 

… puis, dans le process stocké, parsingr les valeurs délimitées par des virgules dans un tableau de strings et faire interroger la table comme si (pseudo-dml):

 ssortingng[] unitArray = @Unit.Split(','); . . . SELECT BLA, BLEE, BLOO FROM F_BUELLER WHERE Unit in unitArray[0], unitArray[1], unitArray[2], // and on for however many units are being queried for 

… ou quoi / comment?

NOTE: Si c'était un projet "normal" (non-SSRS, c'est-à-dire), j'utiliserais simplement le proc stocké original, l'appelant plusieurs fois, et amalgamant datatables returnnées, groupées par Unit. Je ne sais pas si c'est possible ou comment le faire depuis SSRS, dans un file rdl / xml, bien que …

METTRE À JOUR

Ce qui doit vraiment arriver ici, c'est qu'il y ait un saut de page après chaque "Unité" unique, la raison étant que le rapport est exporté vers Excel, et le requestur veut que chaque Unité soit sur sa propre feuille séparée.

Donc, fondamentalement, j'ai besoin d'appeler la même procédure stockée N fois, en plaçant les résultats à chaque fois sur sa propre "page".

L'astuce ici semble donc être bonne ("vous pouvez créer plusieurs sets de données dans Reporting Services, puis les utiliser dans différents éléments du rapport. Ajoutez simplement un élément dans le menu Dataset: dropdown on the data data").

Le point crucial du biscuit est, cependant: comment puis-je fournir 1, et seulement 1, set de données pour chaque unité? Il n'y a aucun moyen de savoir à l'avance combien d'unités / feuilles vont être générées / nécessaires; il pourrait y avoir un couple, il pourrait y avoir quelques dizaines.

La façon dont j'ai fait cela est en passant une string délimitée en tant que paramètre de rapport.

Construire un set de données dans le rapport qui déchiquette la string délimitée en lignes en utilisant la conversion XML. En supposant que le paramètre @Unit est délimité par des virgules lorsqu'il y a plus d'une valeur, la requête de l'set de données ressemblerait à ceci:

 DECLARE @UnitXml XML = CAST('<unit>' + REPLACE(@Unit,',','</unit><unit>') + '</unit>' AS XML) SELECT unit.x.value('.','VARCHAR(200)') AS [unit] FROM @UnitXml.nodes('/unit') AS unit(x) 

Ensuite, créez un tableau masortingciel contenant une ligne pour chaque élément de l'set de données.

Placez un sous-rapport dans le groupe de lignes du tableau. Dans votre cas, le sous-rapport pointe vers une partie de rapport affichant toutes les informations d'une unité et transmettant le numéro d'unité de l'set de données à votre procédure stockée.

La procédure stockée s'exécuterait une fois pour chaque unité. Je réalise que ce n'est ni élégant ni efficace mais c'est SSRS.

Vous pouvez utiliser le paramètre de type de table SQL Server.

Créer un type d'abord dans SQL Server

 CREATE TYPE [dbo].[TVP_Units] AS TABLE( [Units] VARCHAR(1000) ) GO 

La procédure Make Your Stored accepte une variable de ce type au lieu d'une variable Varchar (1000) @Units.

 ALTER PROCEDURE MyProc @TVP_Units [dbo].[TVP_Units] READONLY , @BegDate datetime , @EndDate datetime , @SortBy varchar(20) ....... rest of the code 

Je ne m'attends pas à C # mais votre code C # ressemblerait à quelque chose comme …

 using (con) { //Create a DataTable .... DataTable _dt = new DataTable("Units"); _dt.Columns.Add("Unit", typeof(ssortingng)); _dt.Rows.Add("Unit 1"); _dt.Rows.Add("Unit 2"); _dt.Rows.Add("Unit 3"); SqlCommand sqlCmd = new SqlCommand("dbo.MyProc", con); sqlCmd.CommandType = CommandType.StoredProcedure; SqlParameter tvpParam = sqlCmd.Parameters.AddWithValue("@TVP_Units", _dt); //tells ado.net it is a TVP tvpParam.SqlDbType = SqlDbType.Structured; sqlCmd.Parameters.AddWithValue("@BegDate", YourC#Param); sqlCmd.Parameters.AddWithValue("@EndDate", YourC#Param); sqlCmd.Parameters.AddWithValue("@SortBy", YourC#Param); con.Open(); sqlCmd.ExecuteNonQuery(); }