【问题标题】:Apply WHILE logic on Row-by-Row processing with Cursor使用 Cursor 对 Row-by-Row 处理应用 WHILE 逻辑
【发布时间】:2016-04-29 06:01:13
【问题描述】:

我有解析 MDX 表达式的 T-SQL 脚本。它看起来像:

IF OBJECT_ID ( 'tempdb..#metrics' ) IS NOT NULL
DROP TABLE #metrics

CREATE TABLE #metrics (
Metric VARCHAR(255)
)

---

DECLARE @counter INT = 1

DECLARE @mdx VARCHAR(4000) = 'SELECT {[Measures].[One],[Measures].[Two],[Measures].[Three],[Measures].[Four]} DIMENSION, PROPERTIES OTHER'
DECLARE @startString INT
DECLARE @endString INT
DECLARE @metric VARCHAR(200)

WHILE (1=1)
BEGIN
       -- loop data and process them
       SET @startString = (SELECT PATINDEX('%[[]Measures%',@mdx))
       SET @endString = (SELECT CHARINDEX(',',@mdx))
       SET @metric = (SELECT SUBSTRING(@mdx, @startString, @endString - @startString))

       IF @metric LIKE '%}%'
          BEGIN
             SET @metric = LEFT(@metric, CHARINDEX('}',@metric) - 1)
             INSERT INTO #metrics ( Metric ) SELECT @metric
             SET @mdx = REPLACE(@mdx, @metric, '')
          END
       ELSE
          BEGIN
             INSERT INTO #metrics ( Metric ) SELECT @metric
             SET @metric = @metric + ','
             SET @mdx = REPLACE(@mdx, @metric, '')
          END

    -- break while
    IF @mdx NOT LIKE '%[[]Measures%,%'
       BEGIN
          BREAK;
       END

END

---

SELECT * FROM #metrics

现在,我需要将其应用于更多行,但不知道如何。我用光标尝试过,但它永远不会结束。如何循环以下行的逻辑?

DECLARE @srcTable TABLE (
ID INT
,textData VARCHAR(4000)
)

INSERT INTO @srcTable ( ID, textData ) ( 1, 'SELECT {[Measures].[One],[Measures].[Two],[Measures].[Three],[Measures].[Four]} DIMENSION, PROPERTIES OTHER' )
,(2, 'SELECT {[Measures].[Five],[Measures].[Six],[Measures].[Seven]} DIMENSION, PROPERTIES OTHER' ) 

期望的结果:

1   [Measures].[One]
1   [Measures].[Two]
1   [Measures].[Three]
1   [Measures].[Four]
2   [Measures].[Five]
2   [Measures].[Six]
2   [Measures].[Seven]

【问题讨论】:

    标签: sql-server tsql while-loop cursor sql-server-2014


    【解决方案1】:
    DECLARE @t TABLE (
        ID INT,
        Metric VARCHAR(255)
    )
    
    INSERT INTO @t
    VALUES
        (1, 'SELECT {[Measures].[One],[Measures].[Two],[Measures].[Three],[Measures].[Four]} DIMENSION, PROPERTIES OTHER'),
        (2, 'SELECT {[Measures].[Five],[Measures].[Six],[Measures].[Seven]} DIMENSION, PROPERTIES OTHER') 
    
    SELECT r.ID, item = t.c.value('.', 'VARCHAR(255)') 
    FROM (
        SELECT *, txml = CAST('<r>' + REPLACE(Metric, ',', '</r><r>') + '</r>' AS XML)
        FROM (
            SELECT ID, Metric = SUBSTRING(Metric, CHARINDEX('{',Metric) + 1, CHARINDEX('}',Metric) - CHARINDEX('{',Metric) - 1)
            FROM @t
        ) t
    ) r
    CROSS APPLY txml.nodes('/r') t(c)
    

    输出 -

    ID          item
    ----------- -----------------------
    1           [Measures].[One]
    1           [Measures].[Two]
    1           [Measures].[Three]
    1           [Measures].[Four]
    2           [Measures].[Five]
    2           [Measures].[Six]
    2           [Measures].[Seven]
    

    【讨论】:

    • 这太棒了,尽管我还不清楚逻辑。您能否也添加六列的版本?我希望我的 src 表总共有 6 列(varchars)。只是一些虚拟数据。
    • @DNac 请检查字符串拆分。 Aaron Bertrand 有一篇关于此的好帖子 - sqlperformance.com/2012/07/t-sql-queries/split-strings
    猜你喜欢
    • 2023-03-24
    • 1970-01-01
    • 2019-09-15
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多