【问题标题】:SQL affected row count from a batch of statementsSQL 影响了一批语句的行数
【发布时间】:2012-03-16 17:07:21
【问题描述】:

我正在循环运行以下一批语句,直到受影响的行数返回为 0:

DECLARE @ScopeTable TABLE (  KeyField bigint,  PRIMARY KEY ( KeyField ) )

INSERT INTO @ScopeTable
SELECT DISTINCT DocumentID FROM [CurrentArchive].[dbo].[ItemData]
WHERE DocumentID IS NOT NULL 

INSERT INTO [CurrentArchive].[dbo].[ItemExtras] 
SELECT TOP 1024 [ItemExtras].*
FROM [ItemExtras]
LEFT OUTER JOIN [CurrentArchive].[dbo].[ItemExtras] AS TargetTable
    ON [ItemExtras].DocumentID = TargetTable.DocumentID
INNER JOIN @ScopeTable AS ScopeTable
    ON [ItemExtras].[DocumentID] = ScopeTable.KeyField
WHERE (TargetTable.DocumentID IS NULL)

多年来,它在许多不同的数据库上都能正常工作,但突然在一个特定的数据库上,它返回 38563,这显然是“INSERT INTO @ScopeTable”部分中的行数,因为另一个插入执行“TOP 1024 英寸。

是否有一些 SQL Server 设置可以使它改变这样的行为?依赖于返回 0 是否不当?

编辑:根据要求,这是运行循环的 (Delphi) 代码。 DataAccess.NewCommand 使用一个 TADOCommand,如果它得到一个异常,返回 -1:

TopClause := '';
TopCount := 2048;
Finished := false;
while not Finished do
begin
   AffectedRecords := fDataAccess.NewCommand(Format(
      '%s INSERT INTO %s SELECT%s%s [%s].* FROM [%s] %s',
      [PreClause, QualifiedTable, ManyToOneClause, TopClause, Table, Table, WhereClause]));

   if AffectedRecords >= 0 then
   begin
      if TopClause = '' then // first time through
         Finished := true
      else if AffectedRecords < TopCount then // other times through
         Finished := true;
   end
   else
   begin
      // if that fails, try top 1024, 512, etc until we reach 0 or it succeeds
      TopCount := TopCount div 2;
      if TopCount = 0 then
      begin
         fTracker.LastError := 'Failed to insert items for table ' + QualifiedTable;
         raise Exception.Create(fTracker.LastError);
      end;
      TopClause := ' TOP ' + IntToStr(TopCount);
   end;
end;

【问题讨论】:

  • 是否可以添加其余的循环代码?所有这些对我来说都很好,但问题可能出在其他地方......

标签: sql-server delphi rowcount


【解决方案1】:

您可以尝试在第一次 INSERT 之前设置 NOCOUNT,然后再将其重置:

DECLARE @ScopeTable TABLE (  KeyField bigint,  PRIMARY KEY ( KeyField ) )

SET NOCOUNT ON

INSERT INTO @ScopeTable
SELECT DISTINCT DocumentID FROM [CurrentArchive].[dbo].[ItemData]
WHERE DocumentID IS NOT NULL 

SET NOCOUNT OFF

INSERT INTO [CurrentArchive].[dbo].[ItemExtras] 
SELECT TOP 1024 [ItemExtras].*
FROM [ItemExtras]
LEFT OUTER JOIN [CurrentArchive].[dbo].[ItemExtras] AS TargetTable
    ON [ItemExtras].DocumentID = TargetTable.DocumentID
INNER JOIN @ScopeTable AS ScopeTable
    ON [ItemExtras].[DocumentID] = ScopeTable.KeyField
WHERE (TargetTable.DocumentID IS NULL)

【讨论】:

    猜你喜欢
    • 2014-02-24
    • 1970-01-01
    • 2021-06-10
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多