0

我正在使用 Sql Server 2012。

我需要从表中选择行进行处理。行数需要是可变的。我需要将我选择的行更新为“正在处理”状态 - 为此我有一个要填充的 guid。

我遇到了几个使用 row_number() 的例子和几个使用 CTE 的方法的例子,但我不确定如何组合它们(或者这是否是正确的策略)。我将不胜感激。

这是我到目前为止所拥有的:

DECLARE @SessionGuid uniqueidentifier,  @rowcount bigint
SELECT @rowcount = 1000
SELECT @sessionguid = newid()

    DECLARE @myProductChanges table (
            ProductChangeId bigint
        ,   ProductTypeId smallint
        ,   SourceSystemId tinyint
        ,   ChangeTypeId tinyint );

    WITH NextPage AS 
    (
       SELECT 
           ProductChangeId, ServiceSessionGuid,
           ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS 'RowNum' 
       FROM dbo.ProductChange
       WHERE 'RowNum' < @rowcount
    )
    UPDATE dbo.ProductChange
    SET ServiceSessionGuid = @sessionguid, ProcessingStateId = 2, UpdatedDate = getdate()
    OUTPUT
        INSERTED.ProductChangeId,
        INSERTED.ProductTypeId,
        INSERTED.SourceSystemId,
        INSERTED.ChangeTypeId
    INTO @myProductChanges
    FROM dbo.ProductChange as pc join NextPage on pc.ProductChangeId = NextPage.ProductChangeId

从这里我将从我的临时表中选择并返回数据:

SELECT mpc.ProductChangeId
    ,   pt.ProductName as ProductType
    ,   ss.Name as SourceSystem
    ,   ct.ChangeDescription as ChangeType
FROM @myProductChanges as mpc 
        join dbo.R_ProductType pt on mpc.ProductTypeId = pt.ProductTypeId
        join dbo.R_SourceSystem ss on mpc.SourceSystemId = ss.SourceSystemId
        join dbo.R_ChangeType ct on mpc.ChangeTypeId = ct.ChangeTypeId
ORDER BY ProductType asc

到目前为止,这对我不起作用。当我尝试运行它时出现错误:

Msg 8114, Level 16, State 5, Line 20
Error converting data type varchar to bigint.

我不清楚我做错了什么 - 所以 - 感谢任何帮助。

谢谢!

顺便说一句,以下是我用来尝试解决此问题的一些问题:

https://stackoverflow.com/questions/9777178

https://stackoverflow.com/questions/3319842

https://stackoverflow.com/questions/6402103

4

2 回答 2

2

这个子查询没有意义:

   SELECT 
       ProductChangeId, ServiceSessionGuid,
       ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS 'RowNum' 
   FROM dbo.ProductChange
   WHERE 'RowNum' < @rowcount

您不能RowNum在同一范围内引用别名(并且您正在尝试比较字符串,而不是别名),因为在WHERE解析子句时,SELECT列表尚未具体化。您需要的是另一个巢:

SELECT ProductChangeId, ServiceSessionGuid, RowNum
FROM (SELECT ProductChangeId, ServiceSessionGuid, 
       ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS RowNum
   FROM dbo.ProductChange
) AS x WHERE RowNum < @rowcount

或者:

SELECT TOP (@rowcount-1) ProductChangeId, ServiceSessionGuid, 
  ROW_NUMBER() OVER (ORDER BY ProductChangeId) AS RowNum
FROM dbo.ProductChange
ORDER BY ProductChangeId

另外请停止使用'alias'- 当您需要分隔别名时(在这种情况下不需要),请使用[square brackets].

于 2013-04-19T01:42:01.767 回答
1

我猜,但我认为你想要<=而不是<如果你想要影响@rowcount行,而不是更少。

另一个提示是 CTE 可以直接更新*,如下所示:

WITH NextPage AS 
(
   SELECT TOP(@rowcount) *           
   FROM dbo.ProductChange
)
UPDATE NextPage
SET ServiceSessionGuid = @sessionguid, ProcessingStateId = 2, UpdatedDate = getdate()
OUTPUT
    INSERTED.ProductChangeId,
    INSERTED.ProductTypeId,
    INSERTED.SourceSystemId,
    INSERTED.ChangeTypeId
INTO @myProductChanges

* 更新影响 CTE 中的基表,即 dbo.ProductChange

于 2013-04-19T02:16:37.187 回答