公司使用SQL Server数据库来存储有关其客户及其业务事务的信息。为您的城市引入了新的区号。区号111对于前缀小于500的电话号码保持不变。前缀为500或更大的号码将被分配区号222.客户表中电话列中的所有电话号码都存储为char(12)以下格式的字符串,'999-999-9999'。我必须对Customers表进行适当的更改
尽快使用最少的管理工作。我应该使用哪一个?
一个。
UPDATE Customers SET Phone = ‘222-‘ + SUBSTRING(Phone,5,8)
FROM Customers WHERE SUBSTRING(Phone,1,3) = ‘111’
AND SUBSTRING(Phone,5,3) >= 500
湾
DECLARE PhoneCursor CURSOR FOR
SELECT Phone FROM Customers
WHERE SUBSTRING(Phone,1,3) = 111
AND SUBSTRING(Phone,5,3) >= 500
OPEN PhoneCursor
FETCH NEXT FROM PhoneCursor
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE Customers
SET Phone = ‘222’ + SUBSTRING(Phone,5,8)
WHERE CURRENT OF PhoneCursor
FETCH NEXT FROM PhoneCursor
END
CLOSE PhoneCursor
DEALLOCATE PhoneCursor
答案 0 :(得分:1)
大更新将持有针对数据库的事务,可能需要很长时间......锁定并造成各种破坏。
为此,我建议使用光标在一段时间内传播该负载。
我还做了一个'chunked'更新......就像这样:
DECLARE @Done bit = 0
WHILE @Done = 0
BEGIN
UPDATE TOP(10000)
Customers SET Phone = ‘222-‘ + SUBSTRING(Phone,5,8)
FROM Customers WHERE SUBSTRING(Phone,1,3) = ‘111’
AND SUBSTRING(Phone,5,3) >= 500
IF @@ROWCOUNT = 0
BEGIN
SET @Done = 1
END
END
答案 1 :(得分:1)
在任何大型数据集中光标都会慢得多,谈论几秒钟或几毫秒。它的作用是不会在任何时候将数据库与其他用户锁定一段时间。
这就是为什么对于大型数据集,批处理方法可能是最好的。
一般情况下,我会首先尝试基于集合的方法,如果需要,可以在非工作时间运行。然后我会尝试基于集合的方法,只有在基于集合的速度太慢的情况下才会运行一批记录。
如果你必须光标运行一条记录,那么你的数据库设计可能会出现严重错误。游标通常是最后的手段。不要将它们用于插入/更新或删除。