2010-03-24 90 views
1

我有一個名爲body的列,其中包含我們CMS的正文內容。數據如下:SQL Server:字符串操作,Unpivoting

... {cloak:id = 1.1.1} ... {cloak} ... {cloak:id = 1.1.2} ... {cloak} ... {披風:ID = 1.1.3} ... {斗篷} ...

適度調整了可讀性,例如:

## h5. A formal process for approving and testing all external network connections and changes to the firewall and router configurations? 
{toggle-cloak:id=1.1.1}{tree-plus-icon} *Compliance:* {color:red}{*}Partial{*}{color} (?) 
{cloak:id=1.1.1} || Date: | 2010-03-15 || || Owner: | Brian || || Researched by: | || || Narrative: | Jira tickets are normally used to approve and track network changes\\ || || Artifacts: | Jira.bccampus.ca\\ || || Recommendation: | Need to update policy that no Jira = no change\\ || || Proposed Remedy(ies): | || || Approved Remedy(ies): | || || Date: | || || Reviewed by: | || || Remarks/comments: | || 
{cloak}## h5. Current network diagrams with all connections to cardholder data, including any wireless networks? 
{toggle-cloak:id=1.1.2}{tree-plus-icon} *Compliance:* {color:red}{*}TBD{*}{color} (?) 
{cloak:id=1.1.2} 

我想獲得的外衣值出在以下格式:

requirement_num 
----------------- 
1.1.1 
1.1.2 
1.1.3 

我正在尋找使用聯盟 - 有沒有人有更好的建議?

忘了提:

  • 我不能使用正則表達式,因爲CLR沒有在數據庫上啓用。
  • 這些數字不是順序的。當前記錄從1.1.6跳到1.2.1
  • 我可以保證每個需求編號會有一對 - {toggle-cloak:id=x.y.z}{cloak:id=x.y.z}。我感興趣的是{cloak:id=x.y.z}{cloak}之間的標籤。
+1

這就是所有......一根長串嗎?在一列/行中? *(Bah到你的隱形編輯)* – Aaronaught 2010-03-24 19:25:26

+0

UNIONs?不知道我在那裏跟着你。 – 2010-03-24 19:28:34

+0

@Remus:處理1.1.1相關的第一個查詢,UNION ALL處理1.1.2秒等 – 2010-03-24 19:29:26

回答

2

我可能會用這個函數。喜歡的東西:

create function [dbo].[getCloaks] 
(
@String  varchar(8000) 
) 
returns @tbl table (s varchar(1000)) 
as 
begin 
declare @i int, @j int, @k int 
    select @i = 1 
    while charindex('{cloak:id=', @String, @i) > 0 
    begin 
     select @j = charindex('{cloak:id=', @String, @i) 
     select @k = charindex('}', @String, @j) 
     insert @tbl select substring(@String, @j + 10, @k - @j - 10) 
     select @i = @k + 1 
    end 
    return 
end 
+1

+1:做得好,通過我的測試。你認爲你可以在CTE中做到嗎? – 2010-03-24 19:54:56

1

下面是一個遞歸CTE版本,希望能比一個迭代的UDF快一點:

DECLARE @Data nvarchar(1000) 

SET @Data = N'...{cloak:id=1.1.1}...{cloak}...{cloak:id=1.1.2}...{cloak}...' + 
      N'{cloak:id=1.1.3}...{cloak}...' 

;WITH Cloak_CTE AS 
(
    SELECT 
     CAST(NULL AS nvarchar(50)) AS requirement_num, 
     CHARINDEX('{cloak:id=', @Data) AS start_index, 
     CHARINDEX('}', @Data, CHARINDEX('{cloak:id=', @Data)) AS end_index 

    UNION ALL 

    SELECT 
     CAST(SUBSTRING(@Data, start_index + 10, 
      end_index - start_index - 10) AS nvarchar(50)), 
     CHARINDEX('{cloak:id=', @Data, end_index + 1), 
     CHARINDEX('}', @Data, CHARINDEX('{cloak:id=', @Data, end_index + 1)) 
    FROM Cloak_CTE 
    WHERE start_index > 0 
) 
SELECT requirement_num 
FROM Cloak_CTE 
WHERE requirement_num IS NOT NULL 

應該是相對簡單的調整多行或不同的圖案,或者把這個轉換爲內聯UDF。

+0

對不起,在第一次提取時忽略了一些花括號 - 當我去回答我的回答時,我看到你用'toggle-cloak:id'令牌編輯了,並且意識到我需要左括號,並且有一些東西丟失了在翻譯。我根據您的真實示例測試了更新的SQL,現在它可以工作。 – Aaronaught 2010-03-24 20:11:52

+0

+1:確認 - 完美適用於我。 – 2010-03-25 17:48:37