2011-08-14 13 views
0
... 
<td class="m92_t_col5" id="preis_0">xx</td> 
... 

を置き換える私は、ID = "" 最初でなければなりませんし、クラス= ""MSSQL(TSQL)手順が順番

... 
<td id="preis_0" class="m92_t_col5">xxx</td> 
... 

に変更したいです。これはtsqlで可能ですか? IDまたはクラスのテキストは一般的です...

+0

あなたが達成しようとしているかを説明することはできますか?なぜこれらの属性の順序を変更する必要がありますか? –

+0

私はいくつかのデータを解析しているので、id = "" class = "" – senzacionale

+2

が必要です。クライアントコードでは、このタイプのものをsql、特にここでhtmlがある場所よりも調整する方がはるかに簡単です。あなたのアプリで使用するために、実際のHTMLパーサを入手してください。あなたが注文について気にしているコードが間違っているとします。 –

答えて

2

私はいくつかの石鹸を見つける必要がありますが、あなたの要件を与え、これは望ましい置換を達成する方法の例です。

-- This will probably not perform terribly well for a number of 
-- reasons, not the least of which we are doing lots of string manipulation 
-- within tsql. 
-- Much of this query nonsense could be consolidated into fewer queries 
-- but given the dearth of information, I chose to build out the solution 
-- in a tumbling data anti-pattern 
; 
WITH SAMPLE_DATA AS 
(
    -- gin up some demo data 
    -- with random spacing and ids to make valid test cases 
    select '<td class="m92_t_col5" id="preis_0">xx</td>' AS html 
    union all select '<td id="preis_2" class="m29_t_col5">no fix req</td>' 
    union all select '<td id="preis_49" class="m29_t_col5">no fix req</td>' 
    union all select '<td class="m93_t_col50" id="preis_3">xy</td>' 
    union all select '<td  class="m95_t_col5" style="fuzzy" id="preis_5">xz</td>' 
    union all select '<td id="preis_8" class="m29_t_col5">no fix req</td>' 
) 
, ORDINALS AS 
(
    -- Find the starting position of the keywords 
    SELECT SD.* 
    , CHARINDEX('class=', SD.html, 0) AS class_ordinal 
    , CHARINDEX('id=', SD.html, 0) AS id_ordinal 
    -- You will really need something in here to keep stuff straight 
    -- otherwise when we bring it all back together, it'll be wrong 
    , ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS original_sequence 
    FROM SAMPLE_DATA SD 
) 
, NEEDS_MODIFIED AS 
(
    -- identify the rows that need modified 
    -- and use the ordinals in previous query to find the close position 
    SELECT 
     O.* 
    , CHARINDEX('"', O.html, O.class_ordinal+7) + 1 AS class_ordinal_end_quote 
    , CHARINDEX('"', O.html, O.id_ordinal+4) + 1 AS id_ordinal_end_quote 
    FROM 
     ORDINALS O 
    WHERE 
     O.id_ordinal > O.class_ordinal 
) 
, FIND_PARTS AS 
(
    -- strip out the parts 
    SELECT 
     NM.* 
    , SUBSTRING(NM.html, class_ordinal, class_ordinal_end_quote - class_ordinal) AS class 
    , SUBSTRING(NM.html, id_ordinal, id_ordinal_end_quote - id_ordinal) AS id 
    FROM 
     NEEDS_MODIFIED NM 
) 
, DONE AS 
(
    SELECT 
     -- This is the heart of the matter 
     -- having identified the correct text values for class and id 
     -- we will now perform a triple replace 
     -- Replace 1 is swapping the class text with somthing that should not exist in source 
     -- Replace 2 replaces the id text with our class text 
     -- Replace 3 removes our placeholder value with id 
     REPLACE(REPLACE(REPLACE(FP.html, FP.class, '~~|~'), FP.id, FP.class), '~~|~', FP.id) AS html 
    , FP.original_sequence 
    FROM 
     FIND_PARTS FP 
    UNION ALL 
    SELECT 
     O.html 
    , O.original_sequence 
    FROM 
     ORDINALS O 
    WHERE 
     O.id_ordinal < O.class_ordinal 

) 
SELECT 
    D.html 
FROM 
    DONE D 
ORDER BY 
    D.original_sequence 

入力

<td class="m92_t_col5" id="preis_0">xx</td> 
<td id="preis_2" class="m29_t_col5">no fix req</td> 
<td id="preis_49" class="m29_t_col5">no fix req</td> 
<td class="m93_t_col50" id="preis_3">xy</td> 
<td  class="m95_t_col5" style="fuzzy" id="preis_5">xz</td> 
<td id="preis_8" class="m29_t_col5">no fix req</td> 

出力

<td id="preis_0" class="m92_t_col5">xx</td> 
<td id="preis_2" class="m29_t_col5">no fix req</td> 
<td id="preis_49" class="m29_t_col5">no fix req</td> 
<td id="preis_3" class="m93_t_col50">xy</td> 
<td  id="preis_5" style="fuzzy" class="m95_t_col5">xz</td> 
<td id="preis_8" class="m29_t_col5">no fix req</td> 

いくつかの思考を行った後、あなたはスカラー関数として、そのために頼むしようとされている場合があります。これはおそらくさらにパフォーマンスが悪くなりますが、問題を解決します。

-- Same logic as above, now in function form 
CREATE FUNCTION dbo.ClassIdSwap 
(
    @input varchar(max) 
) 
RETURNS varchar(max) 
AS 
BEGIN 
    DECLARE 
     @class_ordinal int 
    , @class_text varchar(max) 
    , @class_ordinal_end_quote int 
    , @id_ordinal int 
    , @id_text varchar(max) 
    , @id_ordinal_end_quote int 
    , @out_html varchar(max) 

    SELECT 
     @class_ordinal = CHARINDEX('class=', @input, 0) 
    , @id_ordinal = CHARINDEX('id=', @input, 0) 

    SELECT 
     @class_ordinal_end_quote = CHARINDEX('"', @input, @class_ordinal+7) + 1 
    , @id_ordinal_end_quote = CHARINDEX('"', @input, @id_ordinal+4) + 1 

    -- bail out early 
    IF (@id_ordinal < @class_ordinal) 
    BEGIN 
     RETURN @input 
    END 

    SELECT  
     @class_text = SUBSTRING(@input, @class_ordinal, @class_ordinal_end_quote - @class_ordinal) 
    , @id_text = SUBSTRING(@input, @id_ordinal, @id_ordinal_end_quote - @id_ordinal) 

    RETURN (REPLACE(REPLACE(REPLACE(@input, @class_text, '~~|~'), @id_text, @class_text), '~~|~', @id_text)) 

END 

使用

; 
WITH SAMPLE_DATA AS 
(
    -- gin up some demo data 
    -- with random spacing and ids to make valid test cases 
    select '<td class="m92_t_col5" id="preis_0">xx</td>' AS html 
    union all select '<td id="preis_2" class="m29_t_col5">no fix req</td>' 
    union all select '<td id="preis_49" class="m29_t_col5">no fix req</td>' 
    union all select '<td class="m93_t_col50" id="preis_3">xy</td>' 
    union all select '<td  class="m95_t_col5" style="fuzzy" id="preis_5">xz</td>' 
    union all select '<td id="preis_8" class="m29_t_col5">no fix req</td>' 
) 
SELECT 
    D.html 
, dbo.ClassIdSwap(D.html) AS modified  
FROM 
    SAMPLE_DATA D 
+0

あなたは私の日を保存します。 THX! – senzacionale