【问题标题】:Is there any alternative method for Cursor in SQL Server?SQL Server 中的 Cursor 是否有任何替代方法?
【发布时间】:2017-04-17 06:01:05
【问题描述】:
ALTER PROCEDURE [dbo].[sp_Curing_log_data] 
AS
BEGIN

SET NOCOUNT ON;
BEGIN TRY

DECLARE @Rdatetime AS Datetime
DECLARE @Barcode AS Varchar(15)
DECLARE @Cavity AS Varchar(5)
DECLARE @IPLH AS Float
DECLARE @IPRH AS Float
DECLARE @ITLH AS Float
DECLARE @ITRH AS Float
DECLARE @PTLH AS Float
DECLARE @PTRH AS Float
DECLARE @SPLH AS Float
DECLARE @SPRH AS Float
DECLARE @MachineID AS Varchar(15)
DECLARE @ShiftID AS Varchar(5)
DECLARE @C_Flag AS Int


DECLARE @MyCursor CURSOR

SET @MyCursor = CURSOR FAST_FORWARD

FOR

select TOP (10000) * from [10.65.84.4].[CEAT].dbo.Curing_Trend with(NOLOCK) order by Rdatetime asc

OPEN @Mycursor

FETCH NEXT FROM @MyCursor
INTO 
@Rdatetime,@Barcode,@Cavity,@IPLH,@IPRH,@ITLH,@ITRH,@PTLH,@PTRH,@SPLH,@SPRH,@MachineID,@ShiftID,@C_Flag
        WHILE @@FETCH_STATUS = 0
        BEGIN

            INSERT INTO dbo.Curing_Trend (Rdatetime, Barcode, Cavity, IPLH, IPRH, ITLH, ITRH, PTLH, PTRH, SPLH, SPRH, MachineID, ShiftID)
            values(@Rdatetime,@Barcode,@Cavity,@IPLH,@IPRH,@ITLH,@ITRH,@PTLH,@PTRH,@SPLH,@SPRH,@MachineID,@ShiftID)

            Update [10.65.84.4].[CEAT].dbo.Curing_Trend SET C_Flag = 0 where Rdatetime = @Rdatetime and Barcode = @Barcode

            FETCH NEXT FROM @MyCursor
            INTO @Rdatetime,@Barcode,@Cavity,@IPLH,@IPRH,@ITLH,@ITRH,@PTLH,@PTRH,@SPLH,@SPRH,@MachineID,@ShiftID,@C_Flag
        END
        CLOSE @MyCursor
        DEALLOCATE @MyCursor
        Delete from [10.65.84.4].[CEAT].dbo.Curing_Trend  where C_Flag =0
    END TRY
    BEGIN CATCH
            EXEC [dbo].[sp_InsertErrorDetails]
            Return 2
        END CATCH
    END

这是我将数据从一台服务器传输到另一台服务器的过程,因为大约有数百万个数据游标无效。

请任何人提出替代光标的替代方法。

提前致谢

【问题讨论】:

  • 您是要传输整个表,还是仅传输数据子集?
  • 我正在将 100000 个数据从一个表传输到另一个表。在游标中运行需要很长时间。
  • 如果您想传输整个表,请使用 bcp in/out。如果您要传输数据子集,PK/集群键是什么键?
  • 亲爱的@Greg 我正在使用链接服务器将数据从一个表传输到另一个表。所以我不能使用 BCP,
  • 表中没有PK

标签: sql-server stored-procedures sql-server-2012 sql-server-2008-r2 cursor


【解决方案1】:

您可以像这样批量使用Insertdelete

INSERT INTO dbo.Curing_Trend (Rdatetime, Barcode, Cavity, 
IPLH, IPRH, ITLH, ITRH, PTLH, PTRH, SPLH, SPRH, MachineID, ShiftID)      
    SELECT TOP (10000) 
        t.Rdatetime, t.Barcode, t.Cavity, t.IPLH,
        t.IPRH, t.ITLH, t.ITRH, t.PTLH, t.PTRH,
        t.SPLH, t.SPRH, t.MachineID, t.ShiftID 
    FROM
        [10.65.84.4].[CEAT].dbo.Curing_Trend ct  
    ORDER BY
        Rdatetime ASC

; WITH cte AS
(
   SELECT TOP 10000 *
   FROM [10.65.84.4].[CEAT].dbo.Curing_Trend ct  
   ORDER BY Rdatetime ASC
)
DELETE FROM cte

【讨论】:

  • 如果在 INSERT 完成和 DELETE 语句开始之间插入了新行,这将导致问题,您可能会删除新行,但它们没有被插入。
【解决方案2】:

使用OUTPUT 子句,您可以在一个查询中完成。如果需要,您也可以按 C_Flag 进行过滤。

; WITH cte AS
(
   SELECT TOP 10000 *
   FROM [10.65.84.4].[CEAT].dbo.Curing_Trend ct  
   ORDER BY Rdatetime ASC
)
DELETE
FROM cte
OUTPUT Rdatetime, Barcode, Cavity, IPLH, IPRH, ITLH, ITRH, PTLH, PTRH, SPLH, SPRH, MachineID, ShiftID
INTO [CEAT].dbo.Curing_Trend (Rdatetime, Barcode, Cavity, IPLH, IPRH, ITLH, ITRH, PTLH, PTRH, SPLH, SPRH, MachineID, ShiftID)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 2011-04-21
    • 2020-01-30
    • 2023-03-27
    • 1970-01-01
    • 2017-09-16
    相关资源
    最近更新 更多