Как оптимизировать курсор на запрос оператора Set? - PullRequest
0 голосов
/ 03 февраля 2020

У меня был курсор в моей хранимой процедуре. Я обновил до l oop, чтобы выполнить быстрее. Но мои циклы пока занимают столько же времени. Пожалуйста, помогите мне отладить мой сценарий. Пожалуйста, найдите мой код ниже.

Мне нужна помощь в обновлении курсора для установки оператора на основе запроса в MS SQL

DECLARE @orderArray INT
    ,@LeftTSMKEY NVARCHAR(250)
    ,@ListElid NVARCHAR(250)
    ,@ListType NVARCHAR(250)
    ,@ListType_Prev NVARCHAR(250)

SET @ListType_Prev = ''
SET @inc = 0

DECLARE cursql CURSOR
FOR
SELECT ListElid
    ,ListType
    ,orderArray
    ,LeftTSMKEY
FROM QAT_ListElid
ORDER BY ListType
    ,orderArray

OPEN cursql

FETCH NEXT
FROM cursql
INTO @ListElid
    ,@ListType
    ,@orderArray
    ,@LeftTSMKEY

WHILE (@@Fetch_status = 0)
BEGIN
    IF @ListType <> @ListType_Prev
    BEGIN
        SET @inc = 0
        SET @ListType_Prev = @ListType
    END
    ELSE IF @ListType = @ListType_Prev
    BEGIN
        SET @inc = @inc + 1
    END

    IF @inc <> @orderArray
    BEGIN
        INSERT [QAT_ListElid2] (
            [ListElid]
            ,[ListType]
            ,[orderArray]
            ,[LeftTSMKEY]
            )
        VALUES (
            @ListElid
            ,@ListType
            ,@inc
            ,@LeftTSMKEY + CAST(@inc AS NVARCHAR(10)) + ']'
            )
    END

    FETCH NEXT
    FROM cursql
    INTO @ListElid
        ,@ListType
        ,@orderArray
        ,@LeftTSMKEY
END

CLOSE cursql

DEALLOCATE cursql

Ниже приведены образцы данных

enter image description here

ListElid    ListType    orderArray  LeftTSMKEY
1000:odl5:7pt_ToxAcuDo[0]   1000:odl5:7pt_ToxAcuDo  0   ToxAcuDo[
106i:odl5:7pt_ToxAcuDo[0]   106i:odl5:7pt_ToxAcuDo  0   ToxAcuDo[
107:107:7pt_NIL[0]  107:107:7pt_NIL 0   NIL[
107:1827:7pt_NIL[0] 107:1827:7pt_NIL    0   NIL[
107:1827:7pt_NIL[1] 107:1827:7pt_NIL    1   NIL[
107:1827:7pt_NIL[3] 107:1827:7pt_NIL    3   NIL[
107:1hqn:7pt_NIL[0] 107:1hqn:7pt_NIL    0   NIL[
107:1hqn:7pt_NIL[1] 107:1hqn:7pt_NIL    1   NIL[
107:1rj7:7pt_NIL[0] 107:1rj7:7pt_NIL    0   NIL[
107:1rj7:7pt_NIL[1] 107:1rj7:7pt_NIL    1   NIL[
107:1rsg:7pt_NIL[0] 107:1rsg:7pt_NIL    0   NIL[
107:1s2r:7pt_NIL[0] 107:1s2r:7pt_NIL    0   NIL[
107:1s2r:7pt_NIL[1] 107:1s2r:7pt_NIL    1   NIL[
107:1s2r:7pt_NIL[2] 107:1s2r:7pt_NIL    2   NIL[
107:1s2r:7pt_NIL[4] 107:1s2r:7pt_NIL    4   NIL[
107:1vf:7pt_ NIL[0] 107:1vf:7pt_NIL    0    NIL[

Ответы [ 2 ]

1 голос
/ 03 февраля 2020

Если я правильно понимаю вопрос, следующее утверждение является возможным решением.

Таблицы:

CREATE TABLE QAT_ListElid (
    ListElid nvarchar(250),  
    ListType nvarchar(250), 
    orderArray int, 
    LeftTSMKEY nvarchar(250)
)
INSERT INTO QAT_ListElid
    (ListElid, ListType, orderArray, LeftTSMKEY)
VALUES
    ('1000:odl5:7pt_ToxAcuDo[0]',   '1000:odl5:7pt_ToxAcuDo',   0, 'ToxAcuDo['),
    ('106i:odl5:7pt_ToxAcuDo[0]',   '106i:odl5:7pt_ToxAcuDo',   0, 'ToxAcuDo['),
    ('107:107:7pt_NIL[0]',          '107:107:7pt_NIL',          0, 'NIL['),
    ('107:1827:7pt_NIL[0]',         '107:1827:7pt_NIL',         0, 'NIL['),         -- 107:1827:7pt_NIL
    ('107:1827:7pt_NIL[1]',         '107:1827:7pt_NIL',         1, 'NIL['),         -- 107:1827:7pt_NIL
    ('107:1827:7pt_NIL[3]',         '107:1827:7pt_NIL',         3, 'NIL['),         -- 107:1827:7pt_NIL
    ('107:1hqn:7pt_NIL[0]',         '107:1hqn:7pt_NIL',         0, 'NIL['),
    ('107:1hqn:7pt_NIL[1]',         '107:1hqn:7pt_NIL',         1, 'NIL['),
    ('107:1rj7:7pt_NIL[0]',         '107:1rj7:7pt_NIL',         0, 'NIL['),
    ('107:1rj7:7pt_NIL[1]',         '107:1rj7:7pt_NIL',         1, 'NIL['),
    ('107:1rsg:7pt_NIL[0]',         '107:1rsg:7pt_NIL',         0, 'NIL['),
    ('107:1s2r:7pt_NIL[0]',         '107:1s2r:7pt_NIL',         0, 'NIL['),         -- 107:1s2r:7pt_NIL
    ('107:1s2r:7pt_NIL[1]',         '107:1s2r:7pt_NIL',         1, 'NIL['),         -- 107:1s2r:7pt_NIL
    ('107:1s2r:7pt_NIL[2]',         '107:1s2r:7pt_NIL',         2, 'NIL['),         -- 107:1s2r:7pt_NIL
    ('107:1s2r:7pt_NIL[4]',         '107:1s2r:7pt_NIL',         4, 'NIL['),         -- 107:1s2r:7pt_NIL
    ('107:1vf:7pt_ NIL[0]',         '107:1vf:7pt_NIL',          0, 'NIL[')
CREATE TABLE QAT_ListElid2 (
    ListElid nvarchar(250),  
    ListType nvarchar(250), 
    orderArray int, 
    LeftTSMKEY nvarchar(250)
)

Заявление:

;WITH ChangesCTE AS (
    SELECT 
        ListElid, ListType, orderArray, LeftTSMKEY,
        CASE 
            WHEN ListType = LAG(ListType) OVER (PARTITION BY ListType ORDER BY orderArray) THEN 1 
            ELSE 0
        END AS [Change]
    FROM QAT_ListElid
), FinalCTE AS (
    SELECT 
        ListElid, ListType, orderArray, LeftTSMKEY,
        SUM([Change]) OVER (PARTITION BY ListType ORDER BY ListType, orderArray) AS [inc]
    FROM ChangesCTE
)
INSERT INTO QAT_ListElid2
    ([ListElid], [ListType], [orderArray], [LeftTSMKEY])
SELECT 
    ListElid, 
    ListType, 
    [inc] AS orderArray, 
    LeftTSMKEY + CAST([inc] as nvarchar(10)) + ']' AS LeftTSMKEY
FROM FinalCTE
WHERE orderArray <> [inc]

или другое утверждение как второй вариант:

INSERT INTO QAT_ListElid2
    ([ListElid], [ListType], [orderArray], [LeftTSMKEY])
SELECT 
    ListElid, 
    ListType, 
    [inc] AS orderArray, 
    LeftTSMKEY + CAST([inc] as nvarchar(10)) + ']' AS LeftTSMKEY
FROM (
    SELECT 
        ListElid, ListType, orderArray, LeftTSMKEY,
        ROW_NUMBER() OVER (PARTITION BY ListType ORDER BY orderArray) - 1 AS [Inc]
    FROM QAT_ListElid
) t
WHERE orderArray <> [inc]

Результат (две вставленные строки):

--------------------------------------------------------------
ListElid            ListType            orderArray  LeftTSMKEY
--------------------------------------------------------------
107:1827:7pt_NIL[3] 107:1827:7pt_NIL    2           NIL[2]
107:1s2r:7pt_NIL[4] 107:1s2r:7pt_NIL    3           NIL[3]
0 голосов
/ 03 февраля 2020

Они основаны на синтаксисе DECLARE CURSOR и используются главным образом в скриптах Transact- SQL, хранимых процедурах и триггерах. Курсоры Transact- SQL реализованы на сервере и управляются операторами Transact- SQL, отправляемыми с клиента на сервер. Они также могут содержаться в пакетах, хранимых процедурах или триггерах.

Как и INT, VARCHAR и другие типы данных, курсоры объявляются в пакетах T- SQL. SQL Сервер поставляется с соответствующими инструкциями для управления им:

  1. OPEN, чтобы сообщить SQL Серверу выполнить запрос и заполнить курсор набором результатов;

  2. ЗАКРЫТЬ, чтобы сообщить SQL серверу об освобождении ресурсов, используемых курсором;

  3. FETCH, чтобы сообщить SQL серверу о получении указанной строки c из курсора. Когда мы используем эту функцию, мы можем получить результат инструкции FETCH в переменной @@ FETCH_STATUS. Если установлено значение 0, это означает, что инструкция выполнена успешно.

...