503 messaggi dal 18 dicembre 2012
Ciao a tutti

Ho una funzione che contiene questa condizione:

AND tb1.codice_struttura NOT IN (@StruttureAttive)

dove @StruttureAttive è un NVarchar(250) passato come parametro.

Non so come passare da c# @StruttureAttive perchè assume valori del tipo:

'cod1','cod2','cod3' o 'cod1'

quindi avrò:

AND tb1.codice_struttura NOT IN ('cod1','cod2','cod3')

Come faccio?

Ho provato a crearmi una stringa del tipo:
string strutture = "'cod1','cod2','cod3'";
cmd.Parameters.AddWithValue("@Strutture", strutture);

ma non va.

Grazie mille
salve,
NON si puo' fare, in quanto tu vorresti passare un "multi argomento" e non un "singolo argomento"...
puoi cioe' passare il parametro par.SqlValue = "colValue1";
che nel codice SQL viene traslato in
SELECT ...
   FROM ....
   WHERE colX NOT IN (@par {che diventa "colValue1"})

ma @par NON puo' ovviamente essere un "multi valore" come intendi tu...
solitamente, si utilizza un
@par nvarchar(8000)
che sara' valorizzato con una comma separated list (tipo par.SqlValue = "val1, val2, val3, ...., valN";)
per poi splittare il valore in un insieme di righe da mettere in join nel codice SQL della procedura/funzione, tipicamente

SET NOCOUNT ON;
USE tempdb;
GO
CREATE TABLE dbo.t (
  Id int NOT NULL PRIMARY KEY,
  Data varchar(10) NOT NULL, 
  ColPar varchar(4) NOT NULL
  );
GO
INSERT INTO dbo.t
  VALUES (1 , 'Data1', 'col1'),
    (2 , 'Data2', 'col2'),
    (3 , 'Data2.2', 'col9'),
    (4 , 'Data3', 'col3'),
    (5 , 'Data3.2', 'col9'),
    (6 , 'Data3.3', 'col9');
GO
DECLARE @values varchar(100) = 'col1,col2,col3';
DECLARE @sep varchar(1) = ',';

PRINT 'split del multivalore in piu'' righe..';
WITH Pieces(pn, startPos, endPos, valueList) AS (
    SELECT 1, 1, CHARINDEX(@sep, @values), @values AS valueList
    UNION ALL
    SELECT pn + 1, endPos + 1, CHARINDEX(@sep, Pieces.valueList , endPos + 1), Pieces.valueList
        FROM Pieces
        WHERE endPos > 0
    ),
singleValue AS (
        SELECT LTRIM(RTRIM(SUBSTRING(Pieces.valueList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END))) AS entry
            FROM Pieces
            WHERE LEN(LTRIM(RTRIM(SUBSTRING(Pieces.valueList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END)))) > 0
    )
    SELECT * FROM singleValue
        OPTION (MAXRECURSION 0);

PRINT 'ergo:';
WITH Pieces(pn, startPos, endPos, valueList) AS (
    SELECT 1, 1, CHARINDEX(@sep, @values), @values AS valueList
    UNION ALL
    SELECT pn + 1, endPos + 1, CHARINDEX(@sep, Pieces.valueList , endPos + 1), Pieces.valueList
        FROM Pieces
        WHERE endPos > 0
    ),
singleValue AS (
        SELECT LTRIM(RTRIM(SUBSTRING(Pieces.valueList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END))) AS entry
            FROM Pieces
            WHERE LEN(LTRIM(RTRIM(SUBSTRING(Pieces.valueList, startPos, CASE WHEN endPos > 0 THEN endPos-startPos ELSE 8000 END)))) > 0
    )
    SELECT * 
    FROM dbo.t t
      LEFT JOIN singleValue s ON s.[entry] = t.[ColPar]
    ---- NOT IN = 
    WHERE s.[entry] IS NULL
    OPTION (MAXRECURSION 0);
    
GO
DROP TABLE dbo.t;
--<---------
split del multivalore in piu' righe..
entry
------
col1
col2
col3

ergo:
Id          Data       ColPar entry
----------- ---------- ------ ---------
3           Data2.2    col9   NULL
5           Data3.2    col9   NULL
6           Data3.3    col9   NULL


occhio pero' ai piani di esecuzione perche' lo split di un multivalore puo' essere impegnativo... c'e' caso che possa convenirti un table valued parameter (https://docs.microsoft.com/en-us/sql/relational-databases/tables/use-table-valued-parameters-database-engine), anche se personalmente non li amo molto...
saluti
Modificato da Andrea Montanari il 14 giugno 2017 23.57 -

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.