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

je veux changer àMSSQL (tsql) procédure remplacement pour

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

Alors id = "" doit être d'abord, puis class = "". Est-ce possible avec tsql? Le texte dans l'identification ou la classe est générique ...

+0

Pouvez-vous expliquer ce que vous essayez d'atteindre? Pourquoi avez-vous besoin de changer l'ordre de ces attributs? –

+0

Parce que je suis l'analyse des données et j'ai besoin id = "" class = "" – senzacionale

+2

Il est beaucoup plus facile de faire des ajustements pour ce genre de chose dans le code client que dans sql, et surtout ici, où vous avez html. Allez chercher un vrai analyseur html à utiliser dans votre application. Si le code que vous vous souciez de la commande, vous le faites mal. –

Répondre

2

Je dois aller trouver du savon mais donné vos conditions, ceci est un exemple de la façon d'accomplir le remplacement désiré.

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

Entrée

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

Sortie

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

Après avoir fait une réflexion, vous pourriez avoir essayé de demander que en fonction scalaire. Cela aura probablement une performance encore pire, mais cela résout le problème.

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

Utilisation

; 
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 vous économisez ma journée. THX! – senzacionale

Questions connexes