您可以在事务中放置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.)
我在本地Windows 8计算机上的数据库中运行SQL Server 2008 R2 10.50.4000.0中的脚本(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
答案 0 :(得分:2)
我相信你的问题在于以下几行:
raiserror('Error Occured: %s', 20, 101,@Msg) with log
首先,让我们看一下RAISERROR的签名:
RAISERROR({msg_id | msg_str | @local_variable}
{,严重性,状态}
[,论证[,... n]])
[WITH option [,... n]]
正如强调的那样,我要关注的是严重性参数。在同一MSDN page内,您将找到以下内容(关于严重性参数):
[severity]用户定义的严重性级别是否与此消息相关联
此外:
任何用户都可以指定从0到18的严重级别。从19到25的严重级别只能由sysadmin固定服务器角色的成员或具有ALTER TRACE权限的用户指定。对于从19到25的严重性级别,需要WITH LOG选项。
到目前为止,这么好。在您的代码段中,我们可以看到通过RAISERROR
生成了严重性级别 20 的错误消息。因此,使用了WITH LOG
选项。
然而,MSDN page也注明:
从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
生成包含所述信息的新错误消息。
答案 1 :(得分:0)
您确实知道每次插入可以插入多组值。
values (), (), ()
有一个最佳的。值的总数应小于1024 看起来你有8个值,所以每个插入128()。
答案 2 :(得分: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'
答案 3 :(得分:0)
UNION看起来像一个语句而不是1290,因此更好
(带有硬编码内容的1290个单独的陈述真让我害怕)