Domanda

Eg. posso scrivere qualcosa di simile a questo codice:

public void InactiveCustomers(IEnumerable<Guid> customerIDs)
{
    //...
    myAdoCommand.CommandText =
        "UPDATE Customer SET Active = 0 WHERE CustomerID in (@CustomerIDs)";
    myAdoCommand.Parameters["@CustomerIDs"].Value = customerIDs;
    //...
}

L'unico modo che conosco è unire il mio IEnumerable e quindi utilizzare la concatenazione di stringhe per creare la mia stringa SQL.

È stato utile?

Soluzione

Generalmente il modo in cui lo fai è passare in un elenco di valori separato da virgole e, all'interno della tua procedura memorizzata, analizzare l'elenco e inserirlo in una tabella temporanea, che puoi quindi utilizzare per i join. A partire da SQL Server 2005 , questa è una pratica standard per la gestione di parametri che devono contenere array.

Ecco un buon articolo su vari modi per affrontare questo problema:

Passaggio di un elenco / array a una procedura memorizzata di SQL Server

Ma per SQL Server 2008 , possiamo finalmente passare le variabili della tabella nelle procedure, definendo prima la tabella come tipo personalizzato.

C'è una buona descrizione di questo (e di altre funzionalità del 2008) in questo articolo:

Introduzione alle nuove funzionalità di programmabilità T-SQL in SQL Server 2008

Altri suggerimenti

Puoi SQL 2008 . Non è uscito da molto tempo, ma è disponibile.

Come menzionato in un commento , Erland Sommarskog ha scritto una serie di articoli su questo argomento (linkato di seguito). Gli articoli sono molto approfonditi e possono servire come materiale di riferimento. Sebbene siano specifici di SQL Server (T-SQL), alcune delle tecniche menzionate potrebbero funzionare anche per altri RDBMS (come l'utilizzo di un tipo di dati XML ):

È possibile utilizzare il tipo di parametro xml:

CREATE PROCEDURE SelectByIdList(@productIds xml) AS

DECLARE @Products TABLE (ID int) 

INSERT INTO @Products (ID) SELECT ParamValues.ID.value('.','VARCHAR(20)')
FROM @productIds.nodes('/Products/id') as ParamValues(ID) 

SELECT * FROM 
    Products
INNER JOIN 
    @Products p
ON    Products.ProductID = p.ID

http://weblogs.asp.net/jgalloway/archive/2007/02/16/passing-lists-to-sql-server-2005-with-xml-parameters.aspx

No. I parametri sono come i valori SQL nell'obbedire alla prima forma normale , in sostanza, ci può solo sii uno ...

Come probabilmente saprai, generare stringhe SQL è un affare rischioso: ti lasci aperto a un iniezione SQL attacco . Finché hai a che fare con GUID in buona fede, dovresti andare bene, ma altrimenti devi essere sicuro di ripulire il tuo input.

Non è possibile passare un elenco come singolo parametro SQl. Puoi string.Unire (',') i GUID come " 0000-0000-0000-0000, 1111-1111-1111-1111 " ma questo sarebbe alto sul sovraccarico del database e davvero non ottimale. E devi passare l'intera stringa come singola istruzione dinamica concatenata, non puoi aggiungerla come parametro.

Domanda:

Da dove prendi il tuo elenco di ID che rappresentano i clienti inattivi?

Il mio suggerimento è di affrontare il problema in modo leggermente diverso. Sposta tutta quella logica nel database, qualcosa del tipo:

    Create procedure usp_DeactivateCustomers 
    @inactive varchar(50) /*or whatever values are required to identify inactive customers*/
    AS    
    UPDATE Customer SET c.Active = 0 
    FROM Customer c JOIN tableB b ON c.CustomerID = b.CustomerID 
    WHERE b.someField = @inactive

E chiamalo come procedura memorizzata:

public void InactiveCustomers(string inactive)
{
    //...
    myAdoCommand.CommandText =
        "usp_DeactivateCustomers";
    myAdoCommand.Parameters["@inactive"].Value = inactive;
    //...
}

Se in un database esiste un elenco di GUID, perché devo trovarli; metterli in un elenco generico; svolgere l'elenco in una variabile CSV / XML / Table, solo per presentarli nuovamente al DB ????? Sono già lì! Mi sto perdendo qualcosa?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top