2012-03-01 2 views
0

私は約50個のテーブルを含むデータベースを持っています。各テーブルには各テーブルに最大1 milionの行が約10-100個あります。テーブル内の特定の列にあるすべての行の特殊文字を検索

データベースが古く、一部の行に特殊文字(見えない文字や奇妙なユニコード)が含まれていて、その文字を削除したいと考えています。私はGoogleのを探していたと私は、特定のタイプのすべての列が一覧表示されます小さなスニペットを見つけ

SELECT 
    OBJECT_NAME(col.OBJECT_ID) AS [TableName] 
    ,col.[name] AS [ColName] 
    ,typ.[name] AS [TypeName] 
FROM 
    sys.all_columns col 
    INNER JOIN sys.types typ 
    ON col.user_type_id = typ.user_type_id 
WHERE 
    col.user_type_id IN (167,231) 
    AND 
    OBJECT_NAME(col.OBJECT_ID) = 'Orders' 

これは、varchar型またはnvarchar型であるすべての列が一覧表示されます。

CREATE FUNCTION AllCharactersInString (@str nvarchar(max)) 
RETURNS TABLE 
AS 
RETURN 
    (SELECT 
     substring(B.main_string,C.int_seq,1) AS character 
    ,Unicode(substring(B.main_string,C.int_seq,1)) AS unicode_value 
    FROM 
     (SELECT 
     @str AS main_string) B,(SELECT 
           A.int_seq 
           FROM 
            (SELECT 
            row_number() OVER (ORDER BY name) AS int_seq 
            FROM 
            sys.all_objects) A 
            WHERE 
            A.int_seq <= len(@str)) C 
    ) 

そして第二:

CREATE FUNCTION ContainsInvisibleCharacter (@str nvarchar(max)) 
RETURNS int 
AS 
BEGIN 
DECLARE @Result Int 
IF exists 
(SELECT 
    * 
    FROM 
    AllCharactersInString(@str) 
    WHERE 
    unicode_value IN (1,9,10,11,12,13,14,28,29,31,129,141,143,144,157,160)) 
BEGIN SET @Result = 1 
    END 
ELSE 
BEGIN SET @Result = 0 
    END 
RETURN @Result 
END 

私の質問

は、私は、文字列に特殊文字が含まれているかどうかを確認する二つの機能、文字列からすべての文字の表を戻し1及び第二のを見つけましたどのようにして2つの関数を1つに結合するか(可能であれば高速化する)、2つ目は、テーブル内のすべての列(特定の型)のすべてのレコードに対してその関数を実行する方法です。

私はこのコードを持っている:

SELECT 
    O.Order_Id 
    ,Rn_Descriptor 
FROM 
    dbo.Order O 
WHERE 
    dbo.ContainsInvisibleCharacter(O.Rn_Descriptor) = 1 
    AND 
    O.Order_Id IN (SELECT TOP 1000 
          Order.Order_Id 
         FROM 
          dbo.Order 
         WHERE 
          Order.Rn_Descriptor IS NOT NULL 
        ) 

をしかし、それはすっごく遅い動作します:/ Mayby不要な文字を削除する最速の方法は何ですか? これらの文字を含む行を見つけてリストし、手動でチェックすることができます。

答えて

1

LIKEを使用すると、これをより効率的に行うことができます。

CREATE FUNCTION ContainsInvisibleCharacter(@str nvarchar(max)) RETURNS int 
AS 
BEGIN 
    RETURN 
     (SELECT CASE WHEN @str LIKE 
     '%[' + NCHAR(1) + NCHAR(9) + NCHAR(10) + NCHAR(11) + NCHAR(12) 
      + NCHAR(13) + NCHAR(14) + NCHAR(28) + NCHAR(29) + NCHAR(31) 
      + NCHAR(129) + NCHAR(141) + NCHAR(143) + NCHAR(144) 
      + NCHAR(157) + NCHAR(160) + ']%' 
     THEN 1 ELSE 0 END) 
END 
関連する問題