0

您可以在事务中放入的 INSERT 语句的数量是否有限制?我收到传输错误,并且在运行语句的过程中连接断开。

我应该只填充一个临时表然后运行一个 INSERT 语句吗?

在事务中插入 1000 多个中间的错误消息...

Msg 233, Level 20, State 0, Line 0
A transport-level error has occurred when receiving results from the server. 
(provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)

我在 SQL Server 2008 R2 10.50.4000.0 中针对本地 Windows 8 机器上的数据库运行脚本(Toshiba Satellite S955,x64 8GB RAM,Intel (R) Core(TM) i5-3317U CPU @ 1.70GHz 1.70 GHz)

declare @currentDatabase nvarchar(255);
select @currentDatabase = DB_NAME();

if CHARINDEX('canada', @currentDatabase) = 0
begin
    print 'Please run this script on the Canada server'
    return
end

begin try
begin transaction
SET IDENTITY_INSERT company_name ON
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010001, '6 Day Dental', 5868, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010002, '7-Eleven', 5869, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
insert into company_name (company_name_id, company_name, display_index, approved_by_administrator, requestor_id, modify_timestamp, active, create_timestamp) values (10000601010003, 'AC Properties', 5870, 1, NULL, '2013-04-08 00:00:00.000', 1, '2013-04-08 00:00:00.000');
-- 1287 more INSERT statements...
SET IDENTITY_INSERT company_name OFF

commit
end try
begin catch
    rollback
    declare @Msg nvarchar(max)
    select @Msg=Error_Message();
    raiserror('Error Occured: %s', 20, 101,@Msg) with log
end catch
4

4 回答 4

2

问题

我相信您的问题在于以下行:

raiserror('Error Occured: %s', 20, 101,@Msg) with log

首先,让我们看一下RAISERROR的签名:

RAISERROR ( { msg_id | msg_str | @local_variable }
{ ,严重性,state }
[ ,argument [ ,...n ] ] )
[ WITH option [ ,...n ] ]

正如所强调的,我要关注的部分是严重性论点。在同一MSDN 页面中,您会发现以下内容(关于严重性参数):

[severity] 是与此消息关联的用户定义的严重性级别

还:

任何用户都可以指定从 0 到 18 的严重级别。从 19 到 25 的严重级别只能由 sysadmin 固定服务器角色的成员或具有 ALTER TRACE 权限的用户指定。对于从 19 到 25 的严重级别,需要 WITH LOG 选项。

到目前为止,一切都很好。从您的代码片段中,我们可以看到正在生成一条严重级别20RAISERROR的错误消息,通过. 因此,WITH LOG使用该选项。

但是,MSDN 页面还指出:

从 20 到 25 的严重程度被认为是致命的。如果遇到致命的严重级别,客户端连接在收到消息后终止,错误记录在错误和应用程序日志中。

因此,实际上,您的呼叫RAISERROR正在终止您的连接。

解决方案

我假设您对该CATCH块的意图是“重新抛出”导致该CATCH块运行的原始错误。如果是这样,请查看以下内容(取自Is there an equivalent in T-SQL to C#'s "throw;" to re-throw exceptions?):

...
BEGIN CATCH
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

    SELECT @ErrorMessage = ERROR_MESSAGE(),
           @ErrorSeverity = ERROR_SEVERITY(),
           @ErrorState = ERROR_STATE();

    -- Use RAISERROR inside the CATCH block to return 
    -- error information about the original error that 
    -- caused execution to jump to the CATCH block.
    RAISERROR (@ErrorMessage, -- Message text.
               @ErrorSeverity, -- Severity.
               @ErrorState -- State.
               );
END CATCH;

这使用ERROR_MESSAGE()ERROR_SEVERITY()ERROR_STATE()来收集有关导致CATCH块运行的错误的信息。然后它RAISERROR用于生成带有所述信息的新错误消息。

于 2013-05-31T18:08:12.127 回答
0

您确实知道每次插入可以插入一组以上的值。

values (), (), ()  

有一个最优的。值的总数应低于 1024。
看起来您有 8 个值,因此每次插入 128 ()。

于 2013-05-01T17:29:35.927 回答
0

UNION 看起来像一个语句而不是 1290,因此更好

(1290 条带有硬编码内容的单独语句真的让我害怕)

于 2013-05-01T20:32:40.107 回答
0

您还可以尝试更基于集合的替代语法。

INSERT INTO dbo.Employee ( LastName, FirstName ) 
          Select 'Smith', 'John'
UNION ALL Select 'Jones', 'Mary'
UNION ALL Select 'Packer', 'Penny'
UNION ALL Select 'Stokes', 'Daryl'
于 2013-05-01T18:29:04.983 回答