5

大量のデータを含む大規模なデータベースがあります。最近、営業および配送部門がアプリケーションの一部を使用して、クライアントのクレジットカード番号を公開して保存していることを知りました。私たちはそれをやめましたが、今では数千の行があります。

特定の列をスキャンして16桁の行(またはダッシュ区切り)を探し、それらをXに置き換える方法を見つけようとしています。

カード番号は大量のテキストに格納されているため、これは単純なUPDATEステートメントではありません。これまでのところ、SQL Serverが正規表現に対応しているかどうかを把握できていません(そうではないようです)。

他のすべてが失敗するのは、PHPを介してこれを行うのが得意だからです...しかし、それは苦痛になります。

4

6 に答える 6

5

WHERELIKE句でPATINDEXを使用する必要があるようです。

このようなもの。同様のものを使用してストアドプロシージャを作成し、すべてのインスタンスを置き換えるまで、特定したさまざまなパラメータ(@patternと@patternlengthをパラメータにする)を使用して呼び出します。

declare @pattern varchar(100), @patternlength int
set @pattern = '[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]'
set @patternlength = 19

update  tableName
set fieldName = 
    LEFT(fieldName, patindex('%'+ @pattern + '%', fieldName)-1) 
    + 'XXXX-XXXX-XXXX-XXXX' 
    + SUBSTRING(fieldName, PATINDEX('%'+ @pattern + '%', fieldName)+@patternlength, LEN(fieldName))
from tableName
where fieldName like '%'+ @pattern + '%'

秘訣は、適切なパターンを見つけて、適切な@patternlength値を設定することです(@patternの長さではなく、機能しません!)

于 2012-06-26T13:26:56.897 に答える
4

特にデータがいくつかの異なる形式である可能性があると述べたので、これをプログラムで行う方が良いと思います。すべてのクレジットカード番号が16桁の長さであるとは限らないことに注意してください(Amexは15、Visaは13または16など)。

さまざまな正規表現をチェックしてコードを検証する機能は、可能であれば、クリーンアップジョブレベルで提供するのが最適です。

于 2012-06-26T13:33:03.793 に答える
1

即興のショーンの答え。

以下は、@ text内の@maskPatternのすべての出現を検索し、それらを「x」に置き換えます。たとえば、@ maskPattern = XXXX-XXXX-XXXX-XXXXの場合、@ textでこのパターンが検出され、すべての出現箇所がXXXX-XXXX-XXXX-XXXXに置き換えられます。出現が見つからない場合は、テキストはそのままになります。

このストアドプロシージャは、maskPatternの先頭の3/4のみをマスクするように操作することもできます。乾杯!

  ALTER PROCEDURE [dbo].[SP_MaskCharacters] @text nvarchar(max),
  @maskPattern nvarchar(500)
  AS
   BEGIN
  DECLARE @numPattern nvarchar(max) = REPLACE(@maskPattern, 'x', '[0-9]')
  DECLARE @patternLength int = LEN(@maskPattern)
  WHILE (@text IS NOT NULL)
  BEGIN
  IF PATINDEX('%' + @numPattern + '%', @text) = 0  BREAK;
  SET @text =
    LEFT(@text, PATINDEX('%' + @numPattern + '%', @text)-1) --Get beginning chars of the input text until first occurance of pattern is found
    + @maskPattern --Append aasking pattern
    + SUBSTRING(@text, PATINDEX('%' + @numPattern + '%', @text) + @patternLength, LEN(@text)) -- Get & append rest of the text found after masking attern
    END
    SELECT @text
END
于 2016-08-27T00:29:56.070 に答える
1

私は最近この状況に直面しました。PatindexとStuffを使用すると役立つはずですが、桁数の異なるCC番号については個別に繰り返す必要があります。

-- For 16 digits CC numbers
UPDATE table
SET    columnname = Stuff (columnname, Patindex(
'%[3-6][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'
, columnname), 16, '################')
WHERE  Patindex(
'%[3-6][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]%'
, columnname) > 0 

于 2021-04-13T09:39:17.103 に答える
0

patindexを使用できます。それはきれいではなく、それを書くためのより簡潔な方法があるかもしれません。ただし、セット、つまり[0-9]を使用できます。

patindex: http: //msdn.microsoft.com/en-us/library/ms188395.aspx

同様の質問:T-SQLのSQLServer正規表現

于 2012-06-26T13:31:32.430 に答える
0

PHPを使用したいこの質問を見つけた人のために、クレジットカード番号(すべての数字、ダッシュ、またはスペース)を取得し、最初と最後の4桁を除くすべてを「X」に置き換える関数を使用します。

ダッシュ付きのクレジットカード番号も受け入れるには、代わりに次の正規表現パターンを使用します。

$cc_regex_pattern = '/(\d{4})(-)?(\d{4})(-)?(\d{4})(-)?(\d{4})/'

ダッシュを削除するcc番号の前処理を削除します。

$compressed_cc_number = preg_replace('/(\ |-)/', '', $credit_card_number);

したがって、置換文字列は次のようになります(パターンのインデックスを変更したため、$ 7に注意してください)。

$cc_regex_replacement = '$1' . $cc_middle_pattern . '$7';

または、必要に応じて、元の質問のように、cc番号全体を置き換えるだけです。

$cc_regex_replacement = 'XXXX$2XXXX$4XXXX$6XXXX';

スペースまたはダッシュの有無にかかわらず、クレジットカード番号の元の関数は次のとおりです。これにより、ダッシュがわかりにくくなり、削除されます。

/**
 * @param integer|string $credit_card_number
 * @return mixed
 */
static function obfuscate_credit_card($credit_card_number)
{

    $compressed_cc_number = preg_replace('/(\ |-)/', '', $credit_card_number);

    $cc_length = strlen($compressed_cc_number);
    $cc_middle_length = $cc_length >= 9 ? $cc_length - 8 : 0;

    //create middle pattern
    $cc_middle_pattern = '';
    for ($i = 0; $i < $cc_middle_length; $i++) {
        $cc_middle_pattern .= 'X';
    }

    //replace cc middle digits with middle pattern
    $cc_regex_pattern = '/(\d{4})(\d+)(\d{4})/';
    $cc_regex_replacement = '$1' . $cc_middle_pattern . '$3';
    $obfuscated_cc = preg_replace($cc_regex_pattern, $cc_regex_replacement, $compressed_cc_number);

    return $obfuscated_cc;
}
于 2018-05-25T20:28:59.963 に答える