それが愚かでそれが機能する場合、それはまだ愚かです。
GDPRについての騒ぎは私に考えさせられました-バックアップに行ってデータを変更/削除する必要がある場合、どのようにそれを行いますか? .bakファイルをクラックして開くのは難しいように思えます。しかし、.txtファイルを開くのは非常に簡単です。
代わりに、データベースをテキストファイルにバックアップして、バックアップから履歴を簡単に削除できるようにできますか?
これは実際のバックアップには適していませんが、テーブルをテキストファイルにダンプする使用例がいくつかあります。その場合、xp_cmdshell
を使用してBCP.EXEを呼び出す別の方法は、を使用することです。 DB_BulkExportSQL# で利用可能なSQLCLRストアドプロシージャ(私が書いた)。次に、File_GZipを使用してファイルを圧縮できます。
以下は、BCP.EXEと比較してDB_BulkExportを使用する利点と欠点です。 :
長所:
xp_cmdshell
を有効にする必要はありませんBIT
表現の制御:1/0、T/F、またはTrue/False。SMALLDATETIME
、DATETIME
、DATE
、TIME
、DATETIME2
、およびDATETIMEOFFSET
形式の制御。短所:
DB_BulkExportはデータのみをエクスポートすることに注意してください。結果セットの構造は記録されません。これは[〜#〜] bcp [〜#〜]と同じで、メインのコミュニティWikiで提供されているソリューションとまったく同じですそこにあるソリューションは照合、計算列、ほとんどの列オプションなどを無視するので、答えは.
Kin で言及されているSQL Serverの別のオプションは mssql-scripter です。これはフリー/オープンソースのマルチプラットフォームのPythonベースのツールです。使用していませんが、データやスキーマ(テーブル、制約など)を再作成するために実行できるDDLまたはDMLステートメントをエクスポートしているようです。区切られたフィールドとしてではなく、INSERT
ステートメントとしてのみデータをエクスポートするように見えます。非常に興味深いように見えますが、「 Issues 」を確認して、使用に影響を与えるものがないことを確認してください。
また、この質問(および主要なコミュニティウィキの回答)はSQL Serverについて言及していますが、GDPRを取り巻く問題はSQL Serverに固有のものではありません。したがって、テーブル(およびスキーマなど)をエクスポートする機能は、MySQLに付属している次の2つのユーティリティで利用できることをお伝えしておきます。
PostgreSQLでも、それに付属する次の2つのユーティリティを使用して同じことができます。
Oracleについては、次のリソースを参照してください。完全に同等の出力ではないにしても、少なくとも非常に近くなると思います(正しい方向に向けてくれて Michael Kutz に感謝します)。
同様のユーティリティがDB2に付属しているかどうかはわかりません。
以下は適切なバックアップソリューションではありません。あなたが仕事を辞め、ドアから出て行く途中で上司にいたずらしたいと思わない限り、それを使うべきではありません。しかし、私はいくつかのことを学び、それを書くことを楽しみました。うまくいけば、他の人々もそうなるでしょう。他の状況で実際に役立つ可能性があるいくつかのETL概念を使用します。完全なスクリプトは下部にあります。これから行うのは次のとおりです。
スキーマを独自のテーブルに書き込む
データベース内の各テーブルを、動的に命名された独自のテキストファイルに書き込みます
テキストファイルからスキーマを新しいDBに再作成します
テキストファイルから各テーブルを再作成して一括挿入する
始める前に:DB全体を実行するには、数百GBのストレージが必要です。チキンが多すぎる場合は、スクリプトの「トップ1000」を投げて.txtファイルのサイズを制限することができ、C:\をどのように埋めたかを上司に説明する必要はありません。
Xp_cmdshellを有効にします-ここで説明します:
https://blog.sqlauthority.com/2007/04/26/sql-server-enable-xp_cmdshell-using-sp_configure/
テーブルが既に存在するかどうかを確認して確認します(以前にスクリプトを実行したことがある場合)。毎回テーブルをドロップする方が簡単です。
if exists (select name from sys.tables st with (Nolock) where name = 'HeaderTable')
begin
drop table HeaderTable
end
SELECT
st.name, sc.name 'Column_Name', t.Name 'Data_type',sc.max_length 'Max_Length',
sc.precision, sc.scale, sc.is_nullable
into HeaderTable
FROM
sys.tables st
inner join sys.columns sc on sc.object_id = st.object_id
INNER JOIN sys.types t ON sc.user_type_id = t.user_type_id
ここで、HeaderTableから*をすばやく選択すると、すべてのテーブル、すべての列、そのデータ型、およびmax_lengthが表示されます。これらを再作成するために必要なすべてのものが表示されます。
ここからがクールになります。カーソルを使用してsys.tablesをループし、それぞれを独自の.txtにダンプします。
一連の変数を使用します。
@tableがカーソルに入ります。進行中に各テーブルの名前を保持します。
@ Database、@ filepath、@ filename、@ filetypeはすべて、動的SQLステートメントのセットを構築するために使用されます。
@sqlは最後のSQLコマンドを保持して、sp_executesqlに配置します。
デリミタと行ターミネータを使用すると、物事は少しトリッキーになります。 |のデフォルトを使用する場合/ r、コメントテーブルで本当に苦労するでしょう。 StackOverflowデータベースのどこでも使用されていないことがわかっているものを使用する必要があります。 newid()、ロケット船、ぎこちない目を使用したり、お気に入りの童謡を使用したりできます。 StackOverflowにまだない限り、何でも。
スクリプトは次のとおりです。
declare @table varchar(255),
@Database varchar(255),
@filepath varchar(255),
@filename varchar(255),
@filetype varchar(255),
@sql nvarchar(max),
@delimiter varchar(255),
@rowterminator varchar(255)
set @Database = 'StackOverflow'
set @filepath = 'C:\Data\' -- fix pretty-print mishandling of not-truly escaped '
set @filetype = '.txt'
set @delimiter = 'WhimmyWhammyWozzle'
set @rowterminator = 'WubaLubaDubDub'
declare c cursor local for
select name from sys.tables with (Nolock)
open c
fetch from c into @table
while @@FETCH_STATUS = 0
begin
SET @filename = @table
--output to txt
set @sql = N'declare @bcp varchar(4000)
set @bcp = ''bcp " select top 10000 * from ' + @table + ' " queryout '
+ @filepath + @filename + @filetype + ' -t "' + @delimiter + '" -r "'
+ @rowterminator + '" -c -T -d ' + @Database + '''
print @bcp
EXECUTE master.dbo.xp_cmdshell @BCP'
print @sql
--exec sp_executesql @sql
fetch next from c into @table
end
close c
deallocate c
貼り付けてF5キーを押した場合に備えて、私は安全装置を取り付けています。誰もがそうすることはないでしょう? exec sp_executesql @sqlは、コメンターを削除するまで実行されません。トップ10000も含めました。
ファイルパスに移動すると、一連のテキストファイルが表示されます。
先に進み、1つを開き、いくつかのデータを変更します。手動で開くことが農民のためであると思われる場合は、Fart.exeを使用して、すべてのテキストファイルを検索して置き換えることができます。
先に進んで、新しいデータベースを作成してください。
ヘッダーテーブルの再作成をハードコーディングし、それを使用して残りを再構築します。
ヘッダーを復元:
if exists (select name from sys.tables where name = 'HeaderTable')
begin
drop table HeaderTable
end
create table HeaderTable
(Table_Name varchar(255),
Column_Name varchar(255),
Data_type varchar(255),
Max_Length varchar(255),
precision varchar(255),
scale varchar(255),
is_nullable varchar(255))
次に、HeaderTableにスキーマを一括挿入します。
set @sql = 'BULK INSERT HeaderTable FROM ''' + @filepath + 'HeaderTable'+ @filetype + ''' WITH (FIELDTERMINATOR = '''
+ @delimiter + ''', ROWTERMINATOR = ''' + @rowterminator + ''')'
print @sql
--exec sp_executesql @sql
We will have to tidy it up a bit, to make the next steps easier:
update HeaderTable
set Max_Length = 'max'
where Max_length = -1
update HeaderTable
set Max_Length = '(' + Max_Length + ')'
update HeaderTable
set Max_Length = ''
where Data_type in ( 'int', 'bigint', 'smallint', 'tinyint',
'date','datetime', 'uniqueidentifier', 'sysname', 'bit')
そして、ここで再び物事がクールになります。 HeaderTableをループして各テーブルを再作成し、CreateステートメントとSTUFF()を連結します。 stuff()がどのように機能するか私に尋ねないでください-古い同僚(Mike Ignatoski)がこれを何年も前に私にくれました。信頼できる情報筋によると、彼はもともとソロモンという名前の男からそれを手に入れました。
declare @table varchar(255),
@column_string nvarchar(max),
@sql nvarchar(max),
@string nvarchar(max),
@filepath varchar(255),
@filename varchar(255),
@filetype varchar(255),
@sql nvarchar(max),
@delimiter varchar(255),
@rowterminator varchar(255)
set @filepath = 'C:\Data\' -- fix pretty-print mishandling of not-truly escaped '
set @filetype = '.txt'
set @delimiter = 'WhimmyWhammyWozzle'
set @rowterminator = 'WubaLubaDubDub'
declare c cursor local for
select distinct Table_Name from HeaderTable
where Table_Name != 'HeaderTable'
open c
fetch from c into @table
while @@FETCH_STATUS = 0
begin
set @string = null
set @string = (select stuff( (
select ', ' + Column_Name + ' ' + Data_type + Max_Length from HeaderTable
where Table_Name = @table
for xml path ('')),1,2,''))
print @string
set @sql = ' if not exists (select top 1 name from sys.tables where name = ''' + @table + ''') begin
create table ' + @table + ' (' + @string + ') end'
print @sql
exec sp_executesql @sql
--populate the table
set @sql = 'BULK INSERT ' + @table + ' FROM ''' + @filepath + @table + '.txt'' WITH (FIELDTERMINATOR = '''
+ @delimiter + ''', ROWTERMINATOR = ''' + @rowterminator + ''' )'
print @sql
exec sp_executesql @sql
fetch next from c into @table
end
close c
deallocate c
これで、データベースがテキストファイルから復元されました。 .bakファイルを歴史のゴミ山に委託することができます!関数、ストアドプロシージャ、ビュー、制約、またはインデックスがない場合。
これが完全なスクリプトです:Bad Idea Jeans Backup:
declare @table varchar(255),
@Database varchar(255),
@filepath varchar(255),
@filename varchar(255),
@filetype varchar(255),
@sql nvarchar(max),
@delimiter varchar(255),
@rowterminator varchar(255)
set @Database = 'StackOverflow'
set @filepath = 'C:\Data\' -- fix pretty-print mishandling of not-truly escaped '
set @filetype = '.txt'
set @delimiter = 'WhimmyWhammyWozzle'
set @rowterminator = 'WubaLubaDubDub'
--create database header
if exists (select name from sys.tables st with (Nolock) where name = 'HeaderTable')
begin
drop table HeaderTable
end
SELECT
st.name, sc.name 'Column_Name', t.Name 'Data_type',sc.max_length 'Max_Length',
sc.precision, sc.scale, sc.is_nullable
into HeaderTable
FROM
sys.tables st
inner join sys.columns sc on sc.object_id = st.object_id
INNER JOIN sys.types t ON sc.user_type_id = t.user_type_id
select * from HeaderTable
declare c cursor local for
select name from sys.tables so with (Nolock)
open c
fetch from c into @table
while @@FETCH_STATUS = 0
begin
SET @filename = @table
--output to txt
set @sql = N'declare @bcp varchar(4000)
set @bcp = ''bcp " select top 10000 * from ' + @table + ' " queryout '
+ @filepath + @filename + @filetype + ' -t "' + @delimiter + '" -r "'
+ @rowterminator + '" -c -T -d ' + @Database + '''
print @bcp
EXECUTE master.dbo.xp_cmdshell @BCP'
print @sql
exec sp_executesql @sql
fetch next from c into @table
end
close c
deallocate c
悪い考えのジーンズの復元:
declare @table varchar(255),
@column_string nvarchar(max),
@sql nvarchar(max),
@string nvarchar(max),
@filepath varchar(255),
@filename varchar(255),
@filetype varchar(255),
@delimiter varchar(255),
@rowterminator varchar(255)
set @filepath = 'C:\Data\' -- fix pretty-print mishandling of not-truly escaped '
set @filetype = '.txt'
set @delimiter = 'WhimmyWhammyWozzle'
set @rowterminator = 'WubaLubaDubDub'
--restore header
if exists (select name from sys.tables where name = 'HeaderTable')
begin
drop table HeaderTable
end
create table HeaderTable
(Table_Name varchar(255),
Column_Name varchar(255),
Data_type varchar(255),
Max_Length varchar(255),
precision varchar(255),
scale varchar(255),
is_nullable varchar(255))
set @sql = 'BULK INSERT HeaderTable FROM ''' + @filepath + 'HeaderTable'+ @filetype + ''' WITH (FIELDTERMINATOR = '''
+ @delimiter + ''', ROWTERMINATOR = ''' + @rowterminator + ''')'
print @sql
exec sp_executesql @sql
--make some changes so that we can concatenate our create tables more easily
update HeaderTable
set Max_Length = 'max'
where Max_length = -1
update HeaderTable
set Max_Length = '(' + Max_Length + ')'
update HeaderTable
set Max_Length = ''
where Data_type in ( 'int', 'bigint', 'smallint', 'tinyint',
'date','datetime', 'uniqueidentifier', 'sysname', 'bit')
select * from HeaderTable
--restore DB
declare c cursor local for
select distinct name from sys.columns
where name != 'HeaderTable'
open c
fetch from c into @table
while @@FETCH_STATUS = 0
begin
set @string = null
set @string = (select stuff( (
select ', ' + Column_Name + ' ' + Data_type + Max_Length from HeaderTable
where name = @table
for xml path ('')),1,2,''))
print @string
set @sql = ' if not exists (select top 1 name from sys.tables where name = ''' + @table + ''') begin
create table ' + @table + ' (' + @string + ') end'
print @sql
--exec sp_executesql @sql
set @sql = 'BULK INSERT ' + @table + ' FROM ' + '' + @filepath + @table + '.txt'' WITH (FIELDTERMINATOR = '''
+ @delimiter + ''', ROWTERMINATOR = ''' + @rowterminator + ''' )'
print @sql
--exec sp_executesql @sql
fetch next from c into @table
end
close c
deallocate c