首先发布的问题,我提前为任何失误道歉。 该表包含分配给团队的记录,初始分配由另一个流程完成。通常,我们必须重新分配代理商的记录,并将其平均分配给团队的其他成员。我们一直在手工做这个,这很麻烦。所以我提出了这个解决方案:
DECLARE @UpdtAgt TABLE (ID INT, Name varchar(25))
INSERT INTO @UpdtAgt
VALUES (1, 'Gandalf')
,(2,'Hank')
,(3,'Icarus')
CREATE TABLE #UpdtQry (TblID varchar(25))
INSERT INTO #UpdtQry
SELECT ShtID
FROM TestUpdate
DECLARE @RowID INT
DECLARE @AgtID INT
DECLARE @Agt varchar(25)
DECLARE @MaxID INT
SET @MaxID = (SELECT COUNT(*) FROM @UpdtAgt)
SET @AgtID = 1
--WHILE ((SELECT COUNT(*) FROM #UpdtQry) > 0)
WHILE EXISTS (SELECT TblID FROM #UpdtQry)
BEGIN
SET @RowID = (SELECT TOP 1 TblID FROM #UpdtQry)
SET @Agt = (SELECT Name FROM @UpdtAgt WHERE ID = @AgtID)
UPDATE TestUpdate
SET Assignment = @Agt
WHERE ShtID = @RowID
DELETE #UpdtQry WHERE TblID = @RowID
IF @AgtID < @MaxID
SET @AgtID = @AgtID + 1
ELSE
SET @AgtID = 1
END
DROP TABLE #UpdtQry
这是我第一次尝试深入开展这项工作。 100行的更新大约需要30秒。 UPDATE表TestUpdate只有CLUSTERED索引。我怎样才能提高效率呢?
编辑:我没有在我的解释中很好地定义@UpdtAgt和#UpdtQry表。 @UpdtAgt将保留正在重新分配记录的代理,并且每次使用时都可能会更改。 #UpdtQry将有一个WHERE子句来定义哪些代理记录将被重新分配,同样,这将随着每次使用而改变。我希望能让这一点更加清晰。再一次,为第一次没有做到这一点道歉。
编辑2:我注释掉旧的WHILE子句并插入了HABO建议的子句。再次感谢HABO。
答案 0 :(得分:1)
我认为这是你正在寻找的东西:
DECLARE @UpdtAgt TABLE
(
ID INT,
Name VARCHAR(25)
)
INSERT @UpdtAgt
VALUES (1, 'Gandalf')
,(2, 'Hank')
,(3, 'Icarus')
UPDATE t
SET t.Assignment = a.Name
FROM TestUpdate AS t
INNER JOIN @UpdtAgt AS a
ON t.ShtID = a.ID
这应该一次完成所有4行。
... P.S
如果你以后创建了原始帖子中的表格,请尝试保持列和变量的命名符合其目的!
在您的示例中,您使用了ID
,AgtID
和ShtID
以及(最令人困惑的)TblID
(我认为他们都是同样的事情? [如果我错了,请纠正我!])。如果你在任何地方调用它AgtID
(并且@AgtID
为变量[@RowID
没有真正的需要],那么一眼就能看到什么&#会更容易39;继续! Assignment
和Name
也是如此。
答案 1 :(得分:0)
因为这是你第一次尝试这样的事情,我想祝贺你有所作为。虽然它不理想(什么是?)但它符合主要目标:它有效。使用称为游标的东西有更好的方法。我使用Microsoft的以下页面提醒自己正确的语法:Click here for full instruction on cursors
话虽如此,这篇文章末尾的代码显示了我对你情况的快速解决方案。请注意以下事项:
@TestUpdate
表,以便查询将在MSSQL中运行而不使用永久表。@UpdtAgt
表设置为临时表。但是,如果定期使用,最好将其作为永久性表格。CLOSE
和DEALLOCATE
语句重要 - 忘记这些会产生相当不愉快的后果。DECLARE @TestUpdate TABLE (ShtID int, Assignment varchar(25)) INSERT INTO @TestUpdate VALUES (1,'Fred') ,(2,'Barney') ,(3,'Fred') ,(4,'Wilma') ,(5,'Betty'),(6,'Leopold'),(7,'Frank'),(8,'Fred') DECLARE @UpdtAgt TABLE (ID INT, Name varchar(25)) INSERT INTO @UpdtAgt VALUES (1, 'Gandalf') ,(2,'Hank') ,(3,'Icarus') DECLARE @recid int DECLARE @AgtID int SET @AgtID=0 DECLARE @MaxID int SET @MaxID = (SELECT COUNT(*) FROM @UpdtAgt) DECLARE assignment_cursor CURSOR FOR SELECT ShtID FROM @TestUpdate OPEN assignment_cursor FETCH NEXT FROM assignment_cursor INTO @recid WHILE @@FETCH_STATUS = 0 BEGIN SET @AgtID = @AgtID + 1 IF @AgtID > @MaxID SET @AgtID = 1 UPDATE @TestUpdate SET Assignment = (SELECT TOP 1 Name FROM @UpdtAgt WHERE ID=@AgtID) FROM @TestUpdate TU WHERE ShtID=@recid FETCH NEXT FROM assignment_cursor INTO @recid END CLOSE assignment_cursor DEALLOCATE assignment_cursor SELECT * FROM @TestUpdate