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

问题描述

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 个参数。

解决方法

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

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

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

Java 示例代码参见 Microsoft SQL Server jdbc driver documentation

如果您使用的是 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 '["[email protected]","[email protected]","[email protected]"]';
GO