我在此视图中有一个Id列,但它从40,000跳到7,000,000。 我不希望我的疯狂存储过程循环,直到达到7,000,000,所以我想知道我是否可以创建一个行号。这将是某种表达方式,但我不知道如何制作它。请协助! 先感谢您。
答案 0 :(得分:0)
关系表没有行号。您可以使用内置的ROW_NUMBER() OVER (ORDER BY ...)
函数将行号投影到结果中。
你的程序有很多很多问题。它使用循环@counter作为查找键(!!!)。它假设迭代之间的密钥稳定性(即假设@ counter + 1 是下一个密钥,忽略任何concurent插入/删除)。它假定循环内的稳定性(没有事务,没有锁定以确保EXISTS的有效性)。
您尝试做的是尝试模拟键集驱动的游标。只需使用键集游标。
答案 1 :(得分:0)
你真的应该做你正在做的更新,而不是循环。但如果你坚持......
declare @ID int
declare @LastID int
select @LastID = 0
while (1 = 1)
begin
select @ID = min(Id)
from [vCategoryClaimsData]
where Id > @LastID
-- if no ID found then we've reached the end of the table
if @ID is null break
-- look up the data for @ID
SELECT @claim_Number = dbo.[vCategoryClaimsData].[Claim No],
...
where Id = @LastID
-- do your processing here
...
-- set @LastID to the ID you just processed
select @LastID = @ID
end
确保已将Id列编入索引。这将允许跳过非顺序Id值。
话虽如此,看起来您正在进行的处理可以使用update语句来处理。这样会更有效率,并消除其他人带来的许多问题。
答案 2 :(得分:0)
如果可以,请尝试重新编写存储过程以使用集合与基于行的处理。
要执行您需要的操作,您将使用ROW_NUMBER函数。为此,我在下面提供了一些示例代码。
USE tempdb
GO
IF OBJECT_ID('tempdb.dbo.IDRownumbersView') IS NOT NULL
DROP VIEW5 dbo.IDRownumbersView
IF OBJECT_ID('tempdb.dbo.IDRownumbersTable') IS NOT NULL
DROP TABLE dbo.IDRownumbersTable
CREATE TABLE dbo.IDRownumbersTable
(
RowID int PRIMARY KEY CLUSTERED
,CharValue varchar(5)
,DateValue datetime
)
INSERT INTO IDRownumbersTable VALUES (10, 'A', GETDATE())
INSERT INTO IDRownumbersTable VALUES (20, 'B', GETDATE())
INSERT INTO IDRownumbersTable VALUES (30, 'C', GETDATE())
INSERT INTO IDRownumbersTable VALUES (40, 'D', GETDATE())
INSERT INTO IDRownumbersTable VALUES (50, 'E', GETDATE())
INSERT INTO IDRownumbersTable VALUES (100, 'F', GETDATE())
INSERT INTO IDRownumbersTable VALUES (110, 'G', GETDATE())
INSERT INTO IDRownumbersTable VALUES (120, 'H', GETDATE())
GO
CREATE VIEW dbo.IDRownumbersView
AS
SELECT ROW_NUMBER() OVER (ORDER BY RowID ASC) AS RowNumber
,RowID
,CharValue
,DateValue
FROM dbo.IDRownumbersTable
GO
SELECT * FROM dbo.IDRownumbersView