2016-10-14 2 views
1

Я хотел знать, можно ли это сделать в SQL Server, чтобы сделать это иначе, чем курсоры, потому что он очень медленный. Имейте курсор, который проверяет строку до себя и IF @Machine <> @MachineCur OR @MachineStatus <> @MachinestatusCur OR @sShift <> @sShiftCur затем выполняет вставку в таблицу.Изменение хранимой процедуры - курсор MSSQL

КОД:.

SET ANSI_NULLS ON 

    GO SET QUOTED_IDENTIFIER ON GO 

    CREATE PROCEDURE [DBO].[MSTATE] @STARTDATE AS DATE, @ENDDATE AS DATE AS 

    BEGIN 

    SET NOCOUNT ON 

    DECLARE @LINE AS VARCHAR(255), @MACHINE AS VARCHAR(255), @OBJECTTYPE AS VARCHAR(15), @INV AS VARCHAR(9), @MACHINESTATUS AS VARCHAR(255), @TIMESTART AS DATETIME, @TIMEEND AS DATETIME, @SSHIFT AS VARCHAR(100), @LINECUR AS VARCHAR(255), @MACHINECUR AS VARCHAR(255), @OBJECTTYPECUR AS VARCHAR(15), @INVCUR AS VARCHAR(9), @MACHINESTATUSCUR AS VARCHAR(255), @TIMESTARTCUR AS DATETIME, @TIMEENDCUR AS DATETIME, @SSHIFTCUR AS VARCHAR(100), @FIRST AS BIT 

    IF @STARTDATE IS NULL SET @STARTDATE = '2015-01-01' 
    IF @ENDDATE IS NULL SET @ENDDATE = GETDATE() 

    TRUNCATE TABLE [DBO].[MSTATETEMP] 

    DECLARE CUR10 CURSOR FOR 

    SELECT [LINE],[MACHINE],[OBJECTTYPE],[INV],[MACHINESTATUS],[TIMESTART],[TIMEEND],[SSHIFT] FROM [DBO].[OEEQSTATEDATAPREVIEW] WHERE TIMESTART >= @STARTDATE AND TIMEEND <= @ENDDATE ORDER BY MACHINE, TIMESTART 


    SET @FIRST = 0 

     OPEN CUR10 
       FETCH NEXT FROM CUR10 INTO @LINE, @MACHINE, @OBJECTTYPE, @INV, @MACHINESTATUS, @TIMESTART, @TIMEEND, @SSHIFT 
      WHILE (@@FETCH_STATUS = 0) 
     BEGIN 

      IF @FIRST = 0 BEGIN 

           SET @LINECUR = @LINE 
           SET @MACHINECUR = @MACHINE 
           SET @OBJECTTYPECUR = @OBJECTTYPE 
           SET @INVCUR = @INV 
           SET @MACHINESTATUSCUR = @MACHINESTATUS 
           SET @TIMESTARTCUR = @TIMESTART 
           SET @TIMEENDCUR = @TIMEEND 
           SET @SSHIFTCUR = @SSHIFT 
           SET @FIRST = 1 
          END  

      IF @MACHINE <> @MACHINECUR OR @MACHINESTATUS <> @MACHINESTATUSCUR OR @SSHIFT <> @SSHIFTCUR 
         BEGIN 
           INSERT INTO [DBO].[MSTATETEMP] (LINE, MACHINE, OBJECTTYPE, INV, MACHINESTATUS, TIMESTART, TIMEEND, SSHIFT) 
           VALUES(@LINECUR, @MACHINECUR, @OBJECTTYPECUR, @INVCUR, @MACHINESTATUSCUR, @TIMESTARTCUR, @TIMESTART, @SSHIFTCUR) 
           SET @LINECUR = @LINE 
           SET @MACHINECUR = @MACHINE 
           SET @OBJECTTYPECUR = @OBJECTTYPE 
           SET @INVCUR = @INV 
           SET @MACHINESTATUSCUR = @MACHINESTATUS 
           SET @TIMESTARTCUR = @TIMESTART 
           SET @TIMEENDCUR = @TIMEEND 
           SET @SSHIFTCUR = @SSHIFT 
         END 
      FETCH NEXT FROM CUR10 INTO @LINE, @MACHINE, @OBJECTTYPE, @INV, @MACHINESTATUS, @TIMESTART, @TIMEEND, @SSHIFT 
     END 
     CLOSE CUR10 
     DEALLOCATE CUR10 

     SELECT LINE, MACHINE, OBJECTTYPE, INV, MACHINESTATUS, TIMESTART, TIMEEND, SSHIFT FROM [DBO].[MSTATETEMP] ORDER BY MACHINE, TIMESTART 

    END 

Результат [ПСЭ] [OEEQSTATEDATAPREVIEW] (вставленная строка будет 1 и 3):

Line Machine OBJECTTYPE INV   MACHINESTATUS TIMESTART    TIMEEND     SSHIFT 
410  410  Linje  Invald  limit kapacitet 2015-11-06 17:00:00.000 2015-11-06 17:10:00.000 Night 
410  410  Linje  Invald  limit kapacitet 2015-11-06 17:20:00.000 2015-11-06 17:30:00.000 Night 
410  410  Linje  Ej invald Avstalld  2015-11-06 19:21:01.000 2015-11-06 19:21:04.000 Night 
+0

Похоже, что вы можете в принципе просто вставлять на основе вашего выбора, присоединяясь к виду и таблице –

+0

Избегайте зацикливания механизмов. Здесь вы можете написать только запрос select с условием, которое вы упомянули в инструкции IF, и вставить его. –

+0

Дело в том, что каждая строка в источнике должна проверять свою указанную выше строку, если критерии IF совпадают или нет (если не вставить). Нужна помощь, как я должен обрабатывать этот сенарио с помощью курсора. – Aikman

ответ

0

Попробуйте использовать СТ для создания уникальных идентификаторов строк, то вы можете сделать простой выбор

WITH CTE AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY Machine,TimeStart,TimeEnd) AS RowNum 
     ,* 
    FROM DBO.OEEQSTATEDATAPREVIEW 
) 
INSERT INTO MSTATETEMP 
(Line,Machine,OBJECTTYPE,INV,MACHINESTATUS,TIMESTART,TIMEEND,SSHIFT) 
SELECT Line,Machine,OBJECTTYPE,INV,MACHINESTATUS,TIMESTART,TIMEEND,SSHIFT 
FROM CTE AS C 
WHERE C.RowNum = 1 
    OR EXISTS 
    (
     SELECT 1 
     FROM CTE AS _C 
     WHERE C.RowNum = _C.RowNum + 1 
      AND (C.Machine <> _C.Machine OR C.MACHINESTATUS <> _C.MACHINESTATUS OR C.SSHIFT <> _C.SSHIFT) 
    ) 
    ; 
+0

сначала нехорошо в CTE, попробовал один выше, но после 7 часов и без вставленной строки я его остановил. я сделал что-то неправильно или это так медленно? – Aikman

Смежные вопросы