È possibile utilizzare questo tipo di istruzione INSERT
insert into tblMyTable (Col1, Col2, Col3)
select 'value1', value, 'value3'
from dbo.values2table('abc,def,ghi,jkl',',',-1) V
Il 'valore', 'valore3' e 'abc, def, ghi, jkl' sono i 3 parametri varchar è necessario per impostare in C# SQLCommand.
Questa è la funzione di supporto richiesta.
CREATE function dbo.values2table
(
@values varchar(max),
@separator varchar(3),
@limit int -- set to -1 for no limit
) returns @res table (id int identity, [value] varchar(max))
as
begin
declare @value varchar(50)
declare @commapos int, @lastpos int
set @commapos = 0
select @lastpos = @commapos, @commapos = charindex(@separator, @values, @lastpos+1)
while @commapos > @lastpos and @limit <> 0
begin
select @value = substring(@values, @lastpos+1, @[email protected])
if @value <> '' begin
insert into @res select ltrim(rtrim(@value))
set @limit = @limit-1
end
select @lastpos = @commapos, @commapos = charindex(@separator, @values, @lastpos+1)
end
select @value = substring(@values, @lastpos+1, len(@values))
if @value <> '' insert into @res select ltrim(rtrim(@value))
return
end
GO
I parametri utilizzati sono:
- '' = delimitatore
- -1 = tutti i valori nella matrice, o N per soli primi elementi N
soluzione è sopra, alternative sotto
Oppure, se si desidera, un approccio puramente CTE non supportato da alcuna funzione di divisione (guarda nti con < < <)
;WITH T(value,delim) AS (
select 'abc,def,ghi', ',' --- <<< plug in the value array and delimiter here
), CTE(ItemData, Seq, I, J) AS (
SELECT
convert(varchar(max),null),
0,
CharIndex(delim, value)+1,
1--case left(value,1) when ' ' then 2 else 1 end
FROM T
UNION ALL
SELECT
convert(varchar(max), subString(value, J, I-J-1)),
Seq+1,
CharIndex(delim, value, I)+1, I
FROM CTE, T
WHERE I > 1 AND J > 0
UNION ALL
SELECT
SubString(value, J, 2000),
Seq+1,
CharIndex(delim, value, I)+1, 0
FROM CTE, T
WHERE I = 1 AND J > 1
)
--- <<< the final insert statement
insert into tblMyTable (Col1, Col2, Col3)
SELECT 'value1', ItemData, 'value3'
FROM CTE
WHERE Seq>0
approccio XML
-- take an XML param
declare @xml xml
set @xml = '<root><item>abc</item><item>def</item><item>ghi</item></root>'
insert into tblMyTable (Col1, Col2, Col3)
SELECT 'value1', n.c.value('.','varchar(max)'), 'value3'
FROM @xml.nodes('/root/item') n(c)
-- heck, start with xml string
declare @xmlstr nvarchar(max)
set @xmlstr = '<root><item>abc</item><item>def</item><item>ghi</item></root>'
insert tblMyTable (Col1, Col2, Col3)
SELECT 'value1', n.c.value('.','varchar(max)'), 'value3'
FROM (select convert(xml,@xmlstr) x) y
cross apply y.x.nodes('/root/item') n(c)
Nel codice C#, si può usare solo 4 linee che iniziano con "inserire tblMyTable ..." e parametrizzare la variabile @xmlstr.
È possibile specificare più righe "valori". In questo caso, avrei generato lo SQL in modo programmatico (è possibile utilizzare anche segnaposti con le risorse di SqlCommand! Non è richiesta alcuna iniezione brutto).Se vuoi veramente passare un "array", considera il tipo XML e una sproc da fare - beh, praticamente solo quello che farebbe il codice C#. È possibile scomporre il tipo XML in un tipo di tabella, ma a spese di uno sproc/T-SQL, non è sicuro se questo sia un approccio che * davvero * vuoi intraprendere. –
Wow, non sapevo che potessi fare più linee "valori" fino ad ora. Segnaposto in SqlCommand()? Puoi darmi un piccolo esempio di cosa stai parlando? L'unico segnaposto di cui ho sentito parlare è ASP.NET ma la mia app è Windows Form ... – snickered
@pst - Hai risposto alla mia domanda ma non posso darti credito poiché è nei commenti. Riprovare nelle risposte se ti interessa ... – snickered