sql - 用数组“插入”

标签 sql tsql sql-server-2008-r2

我想知道是否有办法在值列表中使用“插入”。我正在尝试这样做:

insert into tblMyTable (Col1, Col2, Col3)
     values('value1', value2, 'value3')

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

我正在使用 SQL Server 2008 R2。谢谢各位!

最佳答案

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

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

“值(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

使用的参数是:
  • ',' = 分隔符
  • -1 = 数组中的所有值,或者 N 只代表前 N 项

  • 解决方案在上面,替代方案在下面

    或者,如果您喜欢,纯 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
    

    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)
    

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

    关于sql - 用数组“插入”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4720138/

    相关文章:

    sql-server - 如何检查 SQL Server 表中是否存在列

    sql - 获取多个数据库中某个表的行数

    sql-server - SQL Server:合并中的值不变时,避免更新列

    sql - "select where not exists"查询中的语法错误

    mysql - GROUP BY 不返回每个特定字段的所有行

    php - 样式化 "order by desk"查询表

    sql - 使用 T-SQL 以最小和最大日期分组

    sql-server - 根据搜索文本删除父子记录

    sql - 从标识符中选择 10 Before 和 10 After

    mysql - 从行到最后一行选择