SQL server TVP批量插入超过2000个参数

Posted

技术标签:

【中文标题】SQL server TVP批量插入超过2000个参数【英文标题】:SQL server TVP bulk insert more than 2000 params 【发布时间】:2021-03-08 11:43:49 【问题描述】:
CREATE TABLE EAddressDetails (EAddress varchar(100) NULL))

CREATE TYPE EAddressList AS TABLE (Email VARCHAR(100)))

CREATE PROCEDURE EAddresses_InsertBatch
@EAddressBatch [EAddressList] READONLY
AS
BEGIN
INSERT INTO EAddressDetails (EAddress)
SELECT E.Email FROM @EAddressBatch E
SELECT EAddress
from EAddressDetails
END;

像下面这样执行上面的存储过程


DECLARE @__sp_result int; DECLARE @EAddressBatch EAddressList;
INSERT INTO  @EAddressBatch(EAddress)
SELECT EAddress FROM (VALUES (?),(?)...2000 rows,(?)) s(EAddress);
EXECUTE @__sp_result = EAddresses_InsertBatch @EAddressBatch=@EAddressBatch;
SELECT @__sp_result AS __sp_result;

The incoming request has too many parameters. The server supports a maximum of 2100 parameters. Reduce the number of parameters and resend the request.: S0001

有没有什么有效的方法可以插入超过2100个参数。

【问题讨论】:

看来您最好在这里进行 BULK 操作。 hmm.. 但是设置是使用 TVP。 :( 不确定我的查询在这里是否有效 您在 EAddressDetails 上有插入触发器吗?它是否试图在inserted 虚拟表上使用IN 运算符? 将电子邮件地址作为应用代码中的表值参数传递,而不是单个标量参数。这将更加高效,避免插入表变量,并避免 2100 参数限制。 T-SQL 代码为 DECLARE @__sp_result int;EXECUTE @__sp_result = EAddresses_InsertBatch @EAddressBatch=?;SELECT @__sp_result AS __sp_result; 【参考方案1】:

将电子邮件地址作为应用代码中的表值参数而不是单个标量参数传递。这样会更有效率,避免插入到表变量中,并避免 2100 参数限制。

使用此方法修改后的 T-SQL 代码将是:

DECLARE @__sp_result int;
EXECUTE @__sp_result = EAddresses_InsertBatch @EAddressBatch=?;
SELECT @__sp_result AS __sp_result;

参见Microsoft SQL Server jdbc driver documentation 获取 java 示例代码。

如果您使用的是 SQL Server 2016 或更高版本,则传递列表的另一种方法是使用 JSON 数组参数。下面的例子。

CREATE PROCEDURE EAddresses_InsertBatch
    @EAddressBatch varchar(MAX)
AS
SET NOCOUNT ON;
INSERT INTO EAddressDetails (EAddress)
    SELECT E.Email
    FROM OPENJSON(@EAddressBatch)
    WITH (
        EMail varchar(100) '$'
    ) AS E;
GO

EXEC EAddresses_InsertBatch '["test1@example.com","test2@example.com","test3@example.com"]';
GO

【讨论】:

仍在解决这个问题。不确定这些值将如何传递。 @user3636388,如果您发现该方法更简单,我会在答案中添加一个 JSON 示例。这避免了对表类型的需要。 有没有办法在不改变问题中的程序的情况下发送。我无法控制程序。 上述的工作就像一个魅力。但要求是使用 TVP 而不是更改程序中的任何内容

以上是关于SQL server TVP批量插入超过2000个参数的主要内容,如果未能解决你的问题,请参考以下文章

sql server有批量插入和批量更新的sql语句吗

SQL Server 批量插入是事务性的吗?

sql server 2008r2 向带有索引的表里大批量插入数据

如何写sqlserver2000存储过程?用于批量录入数据,求解

批量从 SQL Server 检索数据

sql server返回插入记录的ID(多条记录)