sql >> データベース >  >> RDS >> Sqlserver

SQL置換関数内の正規表現パターン?

    PATINDEXを使用して、パターン(文字列)オカレンスの最初のインデックスを見つけることができます。次に、STUFFを使用して、一致したパターン(文字列)に別の文字列を詰め込みます。

    各行をループします。不正な各文字を必要なものに置き換えます。あなたの場合、非数値を空白に置き換えてください。内側のループは、現在のセルにループの文字が複数ある場合です。

    DECLARE @counter int
    
    SET @counter = 0
    
    WHILE(@counter < (SELECT MAX(ID_COLUMN) FROM Table))
    BEGIN  
    
        WHILE 1 = 1
        BEGIN
            DECLARE @RetVal varchar(50)
    
            SET @RetVal =  (SELECT Column = STUFF(Column, PATINDEX('%[^0-9.]%', Column),1, '')
            FROM Table
            WHERE ID_COLUMN = @counter)
    
            IF(@RetVal IS NOT NULL)       
              UPDATE Table SET
              Column = @RetVal
              WHERE ID_COLUMN = @counter
            ELSE
                break
        END
    
        SET @counter = @counter + 1
    END
    

    注意:これは遅いです! varchar列があると影響が出る可能性があります。したがって、LTRIMRTRIMを使用すると少し役立つ場合があります。とにかく、遅いです。

    クレジットはこのStackOverFlowの回答に割り当てられます。

    EDITCreditは@srutzkyにも行きます

    編集(@Tmdeanによる)一度に1行を実行する代わりに、この回答をよりセットベースのソリューションに適合させることができます。それでも、1行の数字以外の文字の最大数を繰り返すため、理想的ではありませんが、ほとんどの状況で許容できるはずです。

    WHILE 1 = 1 BEGIN
        WITH q AS
            (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
            FROM Table)
        UPDATE Table
        SET Column = STUFF(Column, q.n, 1, '')
        FROM q
        WHERE Table.ID_Column = q.ID_Column AND q.n != 0;
    
        IF @@ROWCOUNT = 0 BREAK;
    END;
    

    フィールドがまだスクラブされているかどうかを示すビット列をテーブルに保持すると、効率を大幅に向上させることもできます。 (NULLは私の例では「不明」を表し、列のデフォルトである必要があります。)

    DECLARE @done bit = 0;
    WHILE @done = 0 BEGIN
        WITH q AS
            (SELECT ID_Column, PATINDEX('%[^0-9.]%', Column) AS n
            FROM Table
            WHERE COALESCE(Scrubbed_Column, 0) = 0)
        UPDATE Table
        SET Column = STUFF(Column, q.n, 1, ''),
            Scrubbed_Column = 0
        FROM q
        WHERE Table.ID_Column = q.ID_Column AND q.n != 0;
    
        IF @@ROWCOUNT = 0 SET @done = 1;
    
        -- if Scrubbed_Column is still NULL, then the PATINDEX
        -- must have given 0
        UPDATE table
        SET Scrubbed_Column = CASE
            WHEN Scrubbed_Column IS NULL THEN 1
            ELSE NULLIF(Scrubbed_Column, 0)
        END;
    END;
    

    スキーマを変更したくない場合は、これを簡単に適応させて、中間結果をテーブル値変数に格納し、最後に実際のテーブルに適用することができます。



    1. OracleODP.NetおよびEFCodeFirstと連携するようにDbContextを構成するにはどうすればよいですか。

    2. xマイル半径内の他の行のmySQL経度および緯度クエリ

    3. MySQLルートパスワードをリセットする方法

    4. SQLで絶対値を計算する方法