見込み客にデモを行いたい Web アプリがありますが、完全なエクスペリエンスを得るには、既存のデータを使用するのが最善の方法です。確かに、アプリに表示される実際の顧客の名前や住所などでこれを行うことは望ましくありません。SQL Server で varchar または text フィールドをランダム化またはスクランブルする簡単な方法はありますか?
これらの列はどれも、プライマリまたは外部のキーではありません。
見込み客にデモを行いたい Web アプリがありますが、完全なエクスペリエンスを得るには、既存のデータを使用するのが最善の方法です。確かに、アプリに表示される実際の顧客の名前や住所などでこれを行うことは望ましくありません。SQL Server で varchar または text フィールドをランダム化またはスクランブルする簡単な方法はありますか?
これらの列はどれも、プライマリまたは外部のキーではありません。
これは遅い回答ですが、この問題に関するインターネット検索には満足できませんでした. 以下は、customers テーブルの姓と名をシャッフルして新しい名前を作成する例です。
--Replace Customers with your table name
select * from Customers
--Be sure int match your id column datatype
Declare @id int
--Add a WHERE here to select just a subset of your table
DECLARE mycursor CURSOR FOR SELECT id FROM Customers
OPEN mycursor
FETCH NEXT FROM mycursor INTO @id;
WHILE (@@FETCH_STATUS = 0)
BEGIN
--We loop
--Warning: NEWID() is generated once per query, so we update the fullname in two queries.
UPDATE Customers
SET FirstName = (SELECT TOP 1 FirstName FROM Customers ORDER BY NEWID())
WHERE id = @id
UPDATE Customers
SET LastName = (SELECT TOP 1 LastName FROM Customers ORDER BY NEWID())
WHERE id = @id
FETCH NEXT FROM mycursor INTO @id;
END
CLOSE mycursor;
DEALLOCATE mycursor;
select * from Customers
Redgate にはそのためのツールがあります: http://www.red-gate.com/products/SQL_Data_Generator/index.htm
使用しませんでしたが、redgate ツールは非常に優れています。
編集
スクランブルではなくデータを生成しますが、それでも有用です。
フィールド内の文字を変更して、データを 1 回スクランブルしました。したがって、「Mike Smith」という名前があり、すべての i を o に、m を l に、e を a に、s を t に、t を rr に変更すると、次のようになります。
Moke Smoth
Loke Sloth
Loka Sloth
Loka Tloth
Loka Rrlorrh
これは名前を読めなくするのに十分であり、戻ってそれが何であったかを判断することもできません (すでに文字が変更されているいくつかの文字を変更しました)。
データをテーブルに残して、どういうわけかスクランブル形式でのみ表示することはできません。
オプションは、何らかの方法でデータをスクランブリングして置き換えるか、同じ一般的な形式の新しいデータを生成するか、使用するクエリの一部としてデータをスクランブリングする関数(CLRまたはT-SQL)を作成するか、データを暗号化することです。 、この場合、ユーザーが適切な復号化キーも持っている場合にのみ表示できます。
前述のRedGateツールに加えて、データを置き換える場合は、Visual Studio Team Databaseに付属のデータジェネレーター、またはおそらくIntegrationServicesの使用を検討することもできます。後者は、より複雑な変換の恩恵を受ける場合に特に役立ちます。
dbForge には、データ生成用の無料ツールがあります: http://www.devart.com/dbforge/sql/data-generator/
更新が必要な列のリストを作成し、そのリストを単純に反復処理して、何らかの方法で行を更新する動的 SQL を実行できます。ほとんどの目的で十分に安全であるように、(ランダムなソルトを使用して) データを sha1 するだけのかなり基本的なスクランブル関数を作成しました。
if exists (select 1 where object_id('tempdb..#columnsToUpdate') is not null)
begin
drop table #columnsToUpdate
end
create table #columnsToUpdate(tableName varchar(max), columnName varchar(max), max_length int)
if exists (select 1 where object_id('fnGetSanitizedName') is not null)
begin
drop function fnGetSanitizedName
end
if exists (select 1 where object_id('random') is not null)
begin
drop view random
end
if exists (select 1 where object_id('randUniform') is not null)
begin
drop function randUniform
end
GO
create view random(value) as select rand();
go
create function dbo.randUniform() returns real
begin
declare @v real
set @v = (select value from random)
return @v
end
go
CREATE FUNCTION dbo.fnGetSanitizedName
(
@functionName nvarchar(max),
@length int
)
RETURNS varchar(max)
AS
BEGIN
return left(SUBSTRING(master.dbo.fn_varbintohexstr(HashBytes('SHA1', cast(cast(cast(dbo.randUniform() * 10000 as int) as varchar(8)) as varchar(40)) + @functionName)), 3, 32), @length)
END
GO
begin transaction
set nocount on
insert into #columnsToUpdate
select tables.name, columns.name,
case
when types.name = 'nvarchar' then columns.max_length / 2
else columns.max_length
end as max_length
from sys.tables tables
inner join sys.columns columns on tables.object_id=columns.object_id
inner join sys.types types on columns.system_type_id = types.system_type_id
where types.name in ('nvarchar', 'varchar')
declare @tableName varchar(max)
declare @columnName varchar(max)
declare @length int
declare @executingSql varchar(max)
declare tableUpdateCursor cursor
for select tableName, columnName, max_length from #columnsToUpdate
open tableUpdateCursor
fetch next from tableUpdateCursor into @tableName, @columnName, @length
while @@fetch_status = 0
begin
set @executingSql = 'update ' + @tableName + ' set ' + @columnName + ' = dbo.fnGetSanitizedName(' + @columnName + ',' + cast(@length as varchar(max)) + ')'
print @executingSql
exec(@executingSql)
fetch next from tableUpdateCursor into @tableName, @columnName, @length
end
close tableUpdateCursor
deallocate tableUpdateCursor
set nocount off
rollback -- Can remove the rollback when you are sure about what your are doing.
drop table #columnsToUpdate
drop function dbo.fnGetSanitizedName
drop view random
drop function randUniform