0

我的存储过程中有游标。我已经更新到 while 循环以更快地执行。但是我的 while 循环需要同样长的时间。请帮我调试我的脚本。请找到我的以下代码。

我需要帮助更新 Cursor 以在 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

请在下面找到示例数据

在此处输入图像描述

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[
4

2 回答 2

0

如果我正确理解了这个问题,那么下一个陈述是一个可能的解决方案。

表:

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]

或 anotehr 声明作为第二个选项:

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]
于 2020-02-03T08:21:00.923 回答
0

它们基于 DECLARE CURSOR 语法,主要用于 Transact-SQL 脚本、存储过程和触发器。Transact-SQL 游标在服务器上实现,并由从客户端发送到服务器的 Transact-SQL 语句进行管理。它们也可能包含在批处理、存储过程或触发器中。

和其他数据类型一样INTVARCHAR游标是在 T-SQL 批处理中声明的。SQL Server 附带了相关的管理说明:

  1. OPEN 告诉 SQL Server 运行查询并使用结果集填充游标;

  2. CLOSE 告诉 SQL Server 释放游标使用的资源;

  3. FETCH 告诉 SQL Server 从游标中检索特定行。当我们使用这个函数时,我们可以在@@FETCH_STATUS 变量中得到FETCH 指令的结果。如果它设置为 0,这意味着指令成功。

于 2020-02-03T07:00:59.250 回答