Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

thứ tự thay thế thủ tục mssql (tsql)

Tôi cần đi tìm một ít xà phòng nhưng với yêu cầu của bạn, đây là ví dụ về cách đạt được sự thay thế mong muốn.

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

Đầu vào

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

Đầu ra

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

Sau khi thực hiện một số suy nghĩ, bạn có thể đang cố gắng yêu cầu điều đó như một hàm vô hướng. Điều này có thể sẽ có hiệu suất thậm chí còn tồi tệ hơn nhưng nó giải quyết được vấn đề.

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

Cách sử dụng

;
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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cú pháp không chính xác gần ')' gọi thủ tục được lưu trữ với GETDATE

  2. SQL Server - tính toán thời gian đã trôi qua giữa hai dấu ngày giờ ở định dạng HH:MM:SS

  3. Làm cách nào để kết nối ứng dụng Android với SQL Server thông qua jbdc?

  4. ODBC và SQL Server 2008:Không thể sử dụng các câu lệnh đã chuẩn bị sẵn?

  5. Cách lọc các đối tượng trong SQL Server Management Studio (SSMS) - Hướng dẫn SQL Server / TSQL Phần 19