web-dev-qa-db-fra.com

Passer une liste "dans" via la procédure stockée

Comment puis-je construire une procédure stockée qui me permettra de passer (par exemple) un @IDList afin que je puisse écrire:

Select * from Foo Where ID in @IDList

Est-ce faisable?

17
klkitchens
4
dotjoe

Avec SQL2005 et plus, vous pouvez envoyer un tableau à partir du code directement.

D'abord créer un type personnalisé

CREATE TYPE Array AS table (Item varchar(MAX))

Que la procédure stockée.

CREATE PROCEDURE sp_TakeArray
    @array AS Array READONLY
AS BEGIN
    Select * from Foo Where ID in (SELECT Item FROM @array)
END

Puis appelez du code passant dans un jeu de données comme tableau

DataTable items = new DataTable();
items.Columns.Add( "Item", typeof( string ) );

DataRow row = items.NewRow();
row.SetField<string>( "Item", <item to add> );
items.Rows.Add( row );

SqlCommand command = new SqlCommand( "sp_TakeArray", connection );
command.CommandType = CommandType.StoredProcedure;
SqlParameter param = command.Parameters.Add( "@Array", SqlDbType.Structured );
param.Value = items;
param.TypeName = "dbo.Array";

SqlDataReader reader = command.ExecuteReader();
12
bstoney

Écrivez les identifiants individuels au tableau B, tous avec la même "clé" (A GUID peut-être).
[.____] alors, votre requête contre la table A comprendrait

where ID in (select ID from B where key = @TempKey)

(Vous pourriez ensuite supprimer les clés si vous avez fini avec elles. Ou, horodatage et avoir un travail SQL le faire plus tard.)

Avantages :

  • Vous n'envoyez pas de chaîne, ce qui pourrait vous exposer à une injection SQL dans certaines circonstances.
  • Selon votre autre logique d'application, vous n'avez pas à suivre ou écrivez les possibilités à la fois.

Inconvénients :

  • Cela pourrait être extrêmement inefficace, en particulier sous des charges lourdes.
0
Doug L.