2012-07-16 6 views
14

Ho una dichiarazione di SQL come la seguente:Come è possibile fornire un elenco <int> a un parametro SQL?

... 
const string sql = @"UPDATE PLATYPUS 
SET DUCKBILLID = :NEWDUCKBILLID 
WHERE PLATYPUSID IN (:ListOfInts)"; 
... 
ocmd.Parameters.Add("ListOfInts", ??WhatNow??); 

Come posso fornire l'elenco separato da virgole di int, che potrebbe essere un qualsiasi numero (ragionevole *) di valori

  • Con il termine "ragionevole" in questo caso intendo tra uno e un paio di dozzine.
+0

perché non sono stati memorizzati i valori in una stringa separati da una virgola? –

+0

@Groo: Ti rendi conto che questa domanda ha più di quattro anni, spero. –

+0

@ B.ClayShannon: ciao, sì, ho semplicemente notato che molte domande simili sono fondamentalmente la stessa domanda collegata, quindi le ho esaminate tutte e ho aggiunto il link al più vecchio. Non ho nulla con nessuno di questi, volevo solo fare un po 'di pulizia come faccio di solito quando trovo un thread comune. – Groo

risposta

0

UPDATE: Come Lasse fa notare non è possibile ottenere ciò che Argilla sta cercando di fare con il metodo seguito. Sebbene questo passi in una lista di numeri coma, non verrà eseguito come previsto. Purtroppo non posso cancellare questo dato che è la risposta accettata.


provare qualcosa di simile:

ocmd.Parameters.Add("ListOfInts", String.Join(",",myList.ToArray()); 

Il metodo String.Join prende tutti gli elementi di un array e pone il carattere specificato tra di loro.

+0

Perché è stata accettata come risposta? Non puoi davvero farlo in questo modo. –

+6

Perché la risposta corretta è: non può essere fatto in questo modo! Non è possibile fornire un singolo parametro che funzioni in una clausola 'IN' con un parametro stringa. Un parametro con valori di tabella potrebbe funzionare, un parametro stringa ** non ** funzionerà. Ora capisco che tu abbia risposto alla domanda che è stata posta, ma il mio punto è che devi rispondere alla domanda che è stata implicita: come farlo funzionare. Risposta: non può –

+1

Va bene, abbastanza giusto. –

1

Utilizzare il metodo Join di string nella matrice di Ints. Si può citare comma come il separatore

List<int> ints = new List<int>(); 
ints.Add(4); 
ints.Add(6); 
ints.Add(2); 

string concatenatedIds= string.Join(",", ints.ToArray()); 

L'uscita (valore in concatenatedIds) sarà 4,6,2. È possibile utilizzare tale stringa come il valore del parametro per il vostro IN clausola

ocmd.Parameters.Add("ListOfInts",concatenatedIds); 
+5

Sebbene questo aggiunga un parametro alla perfezione, non funzionerà con una clausola 'in (@ListOfInts)' nell'SQL. I parametri non funzionano in questo modo. Povero pensiero, lo so, ma no. –

3

Penso che l'unica soluzione possibile sia il passaggio di valori separati da virgola, che è possibile convertire in una tabella in SQL utilizzando una funzione. Ecco la funzione che sto usando

CREATE FUNCTION dbo.CSVToList (@CSV varchar(3000)) 
    RETURNS @Result TABLE (Value varchar(30)) 
AS 
BEGIN 
    DECLARE @List TABLE 
    (
     Value varchar(30) 
    ) 

    DECLARE 
     @Value varchar(30), 
     @Pos int 

    SET @CSV = LTRIM(RTRIM(@CSV))+ ',' 
    SET @Pos = CHARINDEX(',', @CSV, 1) 

    IF REPLACE(@CSV, ',', '') <> '' 
    BEGIN 
     WHILE @Pos > 0 
     BEGIN 
      SET @Value = LTRIM(RTRIM(LEFT(@CSV, @Pos - 1))) 

      IF @Value <> '' 
       INSERT INTO @List (Value) VALUES (@Value) 

      SET @CSV = RIGHT(@CSV, LEN(@CSV) - @Pos) 
      SET @Pos = CHARINDEX(',', @CSV, 1) 
     END 
    END  

    INSERT @Result 
    SELECT 
     Value 
    FROM 
     @List 

    RETURN 
END 

ed è possibile utilizzare il seguente codice (per esempio) per eseguire le operazioni:

DECLARE @CSV varchar(100) 
SET @CSV = '30,32,34,36,40' 

SELECT 
    ProductID, 
    ProductName, 
    UnitPrice 
FROM 
    Products 
WHERE 
    ProductID IN (SELECT * FROM dbo.CSVToLIst(@CSV)) 

ho preso il codice da qui: http://www.geekzilla.co.uk/view5C09B52C-4600-4B66-9DD7-DCE840D64CBD.htm

spero che aiuta.

+0

Ho dimenticato di dire che è necessario utilizzare il metodo String.join per aggregare tutti i valori e quindi passarli come parametri al codice SQL. –

11

Non è possibile, è necessario creare una funzione di supporto che sostituisce :ListOfInts con (ad esempio) :I0,:I1,:I2... e passare il parametro aggiungendo uno a uno nel codice. La funzione desiderata viene emulata con grazia da Dapper.Net in its list support.

+0

Questa risposta è corretta, al contrario di quella accettata e di quella a 3 con maggiore frequenza. Ovviamente puoi usare * un mucchio * di parametri e iniettarli, ottenendo fondamentalmente un SQL come 'dove id in (@ id1, @ id2, @ id3, ...)'. Inoltre ci sono [parametri con valori di tabella] (http://msdn.microsoft.com/en-us/library/bb675163 (v = vs.110) .aspx) ora, ma non so se/come possono essere sfruttato per utilizzare effettivamente 1 parametro per specificare l'elenco di valori "IN" da confrontare. –

1

Il modo migliore per gestirlo consiste nel mantenere l'elenco nel database, in modo tale da poter scrivere una query di selezione per restituire i valori nell'elenco. La domanda è: come puoi farlo quando i dati provengono dal cliente? Il più delle volte, questi dati vengono selezionati manualmente dall'utente, un record alla volta. In tal caso, è possibile utilizzare una tabella (si pensi: "carrello") che aggiunge i record per i valori uno alla volta, come l'utente li seleziona. Se si tratta di più di un lavoro batch, è possibile che si desideri utilizzare un processo BulkInsert per creare i record.

4

Non si indica quale database si sta utilizzando, ma se si tratta di SQL Server 2008 o successivo, è possibile prendere in considerazione anche Table Valued Parameters.

Per il tuo esempio la complessità aggiunta potrebbe non valere la pena, ma possono essere utili in altri scenari.

Problemi correlati