SQL Update命令超出预期

时间:2014-05-16 13:29:53

标签: sql sql-update

我正在尝试对我的SQL DB(2008 R2)进行更新,但出于某种原因,它的更新速度超出了我的预期。我认为我的where,join和update命令存在问题,但我无法找到有关范围和操作顺序的信息。幸运的是,我正在练习在我在生产中进行更改之前恢复的数据库备份!

我发现this链接似乎相似(加入和更新),但我很难将它应用到我的案例中。

对于testUnitCount为15578,我正在尝试将unitNo从05101更改为05088.出于某种原因,它正在为这个TestNumber移动所有这些的unitNo。它是一个OLAP DB(Cubes),因此所有表格看起来比人们习惯的要复杂得多。我以为这次命令是正确的:

SELECT     DashboardData.TestNumber, TestUnits.unitNo, TestUnitCounts.testUnitCount
FROM         DashboardData INNER JOIN
                      TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                      MeasurementData ON TestUnitCounts.testUnitCountID = MeasurementData.TestUnitCountID INNER JOIN
                      TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID AND 
                      MeasurementData.TestUnitID = TestUnits.testUnitID
                      where unitNo='05101'
                      AND TestNumber='1024'
                      AND TestUnitCounts.testUnitCount='15578'
                      order by testUnitCount asc
                      UPDATE TestUnits
                      SET unitNo='05088' where unitNo='05101'

是否有人知道该命令需要更改为什么所以我只需将testUnitCount更改为15578 for unitNo 05101-> 05088 for Test 1024?为什么要为TestNumber更改所有这些?

这是我尝试同样的CTE。我执行它时会受到0行的影响:

Use OLAP05132014C
GO


WITH QueryName_CTE (unitNo,TestNumber,testUnitCount)
AS
(
SELECT     DashboardData.TestNumber, TestUnits.unitNo, TestUnitCounts.testUnitCount
FROM         DashboardData INNER JOIN
                      TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                      MeasurementData ON TestUnitCounts.testUnitCountID = MeasurementData.TestUnitCountID INNER JOIN
                      TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID AND 
                      MeasurementData.TestUnitID = TestUnits.testUnitID
                      where unitNo='05101'
                      AND TestNumber='1024'
                      AND TestUnitCounts.testUnitCount='15578'
)
Update QueryName_CTE


                      SET unitNo='05088' where unitNo='05101'

3 个答案:

答案 0 :(得分:1)

如上述评论所述,目前正在单独运行更新。将查询更改为更新而不是选择。

将您的查询更改为 -

    UPDATE TestUnits
    SET TestUnits.unitNo = '05088'
    FROM         DashboardData INNER JOIN
                          TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                          MeasurementData ON TestUnitCounts.testUnitCountID = MeasurementData.TestUnitCountID INNER JOIN
                          TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID AND 
                          MeasurementData.TestUnitID = TestUnits.testUnitID
                          where unitNo='05101'
                          AND TestNumber='1024'
                          AND TestUnitCounts.testUnitCount='15578'
                          order by testUnitCount asc

答案 1 :(得分:1)

这是一个Northwind CTE示例。

我认为这就是你要做的。 (更新选择查询中的行,而不是整个表)

以下是Sql Server 2008 R2的MSDN链接。

http://technet.microsoft.com/en-us/library/ms190766%28v=sql.105%29.aspx

以下是示例代码....

Use Northwind
GO


Declare @CustomerID char(5)
Select @CustomerID = 'VINET'

print 'Pre Look'
Select o.CustomerID , o.ShipVia 
    FROM 
        dbo.Orders o where o.CustomerID = @CustomerID

/* Now the CTE.  The CTE gets a result based on the specific customerid */

;WITH cteOrdersForOneCustomer (OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry )
 AS
 (
    SELECT o.OrderID,o.CustomerID,o.EmployeeID,o.OrderDate,o.RequiredDate,o.ShippedDate,o.ShipVia ,o.Freight,o.ShipName,o.ShipAddress,o.ShipCity,o.ShipRegion,o.ShipPostalCode,o.ShipCountry 
    FROM 
        dbo.Orders o where o.CustomerID = @CustomerID
 )

/* Now I update the rows in the CTE, not the entire table */
Update cteOrdersForOneCustomer
    Set ShipVia = 1 where ShipVia = 3


print 'Post Look'
Select o.CustomerID , o.ShipVia 
    FROM 
        dbo.Orders o where o.CustomerID = @CustomerID

APPEND:

使用此策略调试CTE正在进行的操作

declare @CurrentRowCount int 


WITH QueryName_CTE (unitNo,TestNumber,testUnitCount)
AS
(
SELECT     DashboardData.TestNumber, TestUnits.unitNo, TestUnitCounts.testUnitCount
FROM         DashboardData INNER JOIN
                      TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                      MeasurementData ON TestUnitCounts.testUnitCountID = MeasurementData.TestUnitCountID INNER JOIN
                      TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID AND 
                      MeasurementData.TestUnitID = TestUnits.testUnitID
                      where unitNo='05101'
                      AND TestNumber='1024'
                      AND TestUnitCounts.testUnitCount='15578'
)

--Debug Level 1, see if anything is in that table
Select * from QueryName_CTE

/*
--Debug Level 2, see if what you're looking for is in that table
Select * from QueryName_CTE where unitNo='05101'
*/

/*
--After debug 1 and 2....do the update
Update QueryName_CTE
    SET unitNo='05088' where unitNo='05101'
*/  

Select @CurrentRowCount = @@ROWCOUNT

print 'Row Count After "Debug Level 2" or  "After debug 1 and 2....do the update"'
print @CurrentRowCount
print ''

答案 2 :(得分:0)

我认为自从我们开始工作以来我就更新了这个。我的同事使用了一种不同的方法(工作),我不完全确定为什么它没有(直接)使用为问题给出的参数,并且必须使用其他值,但是这是什么修复它。

所以涉及的表格如下:

PQdata table name ---------DashboardData table name----------TestUnits table name
key pqID                   key pqID                          key testUnitID
TestIndex                  TestIndex                         unitNo
                           TestNumber                           |
                           TestUnitID                           |
                               |                                |
                            TestUnitCounts table name------------
                            key testUnitCountID
                            testUnitID
                            testUnitCount

我回过头来根据他的疑问记录下来:

•他需要先看一下:

SELECT     PQdata.pqID, PQdata.TestIndex, TestUnits.unitNo, TestUnits.testUnitID, DashboardData.TestNumber, TestUnitCounts.testUnitCount
FROM         DashboardData INNER JOIN
                      TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                      TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID INNER JOIN
                      PQdata ON DashboardData.pqID = PQdata.pqID
                      where TestNumber='1024'
                      AND unitNo='05101'
                      AND testUnitCount='15578'

•这提供了对应于TestNumber:10204的pqid

•然后他必须为unitNo 05088找到testUnitID:

SELECT     PQdata.pqID, PQdata.TestIndex, TestUnits.unitNo, TestUnits.testUnitID, DashboardData.TestNumber, TestUnitCounts.testUnitCount
FROM         DashboardData INNER JOIN
                      TestUnitCounts ON DashboardData.TestUnitCountID = TestUnitCounts.testUnitCountID INNER JOIN
                      TestUnits ON DashboardData.TestUnitID = TestUnits.testUnitID AND TestUnitCounts.testUnitID = TestUnits.testUnitID INNER JOIN
                      PQdata ON DashboardData.pqID = PQdata.pqID
                      where TestNumber='1024'
                      AND unitNo='05088'

•因此需要将其更改为testUnitID:2971

•另外他必须同样找到原始的testUnitID:2970

•因此,需要更新如下所示:

UPDATE DashboardData SET testUnitID = 2971 WHERE testUnitID = 2970 AND pqID = 10204

这是一种比我尝试过的更圆润的方法(我没有做过)。