'insert into'with array

sni*_*red 8 sql t-sql sql-server-2008-r2

我想知道是否有办法在值列表中使用'insert into'.我正在尝试这样做:

insert into tblMyTable (Col1, Col2, Col3)
     values('value1', value2, 'value3')
Run Code Online (Sandbox Code Playgroud)

所以,我想说的是value2将是一个字符串数组.我将把它放在C#中,但SQL语句是我真正需要的.我知道我可以使用foreach并循环遍历我的数组,但我认为可能有更好的方式类似于SELECT语句:SQL SELECT*FROM XXX WHERE columnName in Array.看起来单个查询比一次查询效率更高.

我正在使用SQL Server 2008 R2.谢谢fellas!

Ric*_*iwi 4

您可以使用这种类型的插入语句

insert into tblMyTable (Col1, Col2, Col3)
select 'value1', value, 'value3'
from dbo.values2table('abc,def,ghi,jkl',',',-1) V
Run Code Online (Sandbox Code Playgroud)

' value ''value3'和 ' abc,def,ghi,jkl'是您需要在 C# SQLCommand 中设置的 3 个 varchar 参数。

这就是需要的支持功能。

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, @commapos-@lastpos-1)
    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
Run Code Online (Sandbox Code Playgroud)

使用的参数是:

  1. ',' = 分隔符
  2. -1 = 数组中的所有值,或 N 表示前 N 项

上面是解决方案,下面是替代方案

或者,如果您喜欢,一种不受任何 split 函数支持的纯粹 CTE 方法(使用 <<< 观看评论)

;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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

在 C# 代码中,您只需使用以“insert tblMyTable ...”开头的 4 行,并参数化 @xmlstr 变量。