SQL Server 2000を実行していますが、すべてのDTSオブジェクトからSQLステートメントをエクスポートして、必要に応じて解析してWikiドキュメントに配置できるようにする必要があります。
それを行う方法はありますか?
各DTSオブジェクトを、プロセス名とファイルヘッダーとして抽出された日付を含むファイル名としてオブジェクト名を使用してテキストファイルにダンプする場合があります。
ありがとう。
SQL Server 2000を実行していますが、すべてのDTSオブジェクトからSQLステートメントをエクスポートして、必要に応じて解析してWikiドキュメントに配置できるようにする必要があります。
それを行う方法はありますか?
各DTSオブジェクトを、プロセス名とファイルヘッダーとして抽出された日付を含むファイル名としてオブジェクト名を使用してテキストファイルにダンプする場合があります。
ありがとう。
作業を節約したいが、数ドル払ってもかまわない場合は、DTSパッケージを完全に文書化するツールがあります。XMLにも出力されるため、これらのSQLステートメントを取得するのは比較的簡単です。
Visual Basic コードとして保存された DTS パッケージのタスクから SQL をダンプするPython 2.6スクリプト (Python 2.5 に簡単に移植可能) があります。
DTS パッケージを VB ファイルに保存する方法については、ConcernedOfTunbridgeWells の投稿を参照してください。VB ファイルを保存したら、この関数を実行します。パッケージのコードを含む VB ファイルと同じ場所にフォルダーを作成し、見つかった SQL コードをダンプします。これは、SQL の出力が CSV ファイル (outExt
パラメーターを参照) に送られるか、「SQL タスクの実行」タスクからのものであると想定し、出力ファイルまたは SQL タスクにちなんで SQL クエリに名前を付けます。パッケージが他に何もしない場合、これは便利な解決策です。
気が向いたら、このコードを自由にクリーンアップしてください。
# from __future__ import with_statement # Version 2.5 requires this.
import os, re
def dump_sql(infile, outExt=r'csv'):
"""Parse a DTS package saved as a .bas file, and dump the SQL code.
Pull out the SQL code and the filename for each task. This process
depends on the way that DTS saves packages as VB modules.
Keyword arguments:
infile - The .bas file defining a DTS package.
outExt - The extension (without a period) of the files exported by the
data pumps in the DTS package. These are used to rename the
extracted SQL scripts. If an extract file does not use this
extension, then the whole name of the extract file is used to
name the SQL script. (default: csv)
The function produces a folder in the same folder that contains the
.bas file. It's named like this: if the .bas file is "DTS package.bas",
then the directory will be named "DTS package_SQL". The SQL scripts are
stored in this folder.
"""
#Declare all of the RE's used in the script here.
basExtRE = re.compile(r'\.bas$', re.IGNORECASE)
outExtRE = re.compile(r'\.' + outExt + r'$', re.IGNORECASE)
startTaskRE = re.compile(r'Set oCustomTask(\d+) = oTask.CustomTask')
startSqlRE = re.compile(
r'oCustomTask(\d+)\.(?:Source)?SQLStatement = "(.*)"( & vbCrLf)?')
nextSqlRE = re.compile(
r'oCustomTask(\d+)\.(?:Source)?SQLStatement = oCustomTask\1\.'
r'(?:Source)?SQLStatement & "(.*)"( & vbCrLf)?')
filenameRE = re.compile(
r'oCustomTask(\d+)\.DestinationObjectName = "(.*)"')
descripRE = re.compile(r'oCustomTask(\d+)\.Description = "(.*)"')
invalidCharsRE = re.compile(r'[][+/*?<>,.;:"=\\|]')
#Read the file
with open(infile, 'r') as f:
#Produce the directory for the SQL scripts.
outfolder = '%s_SQL\\' % basExtRE.sub('', infile)
if not os.path.exists(outfolder):
os.makedirs(outfolder)
taskNum = -1
outfile = ''
sql = []
for line in f:
line = line.rstrip().lstrip()
if taskNum == -1:
#Seek the beginning of a task.
m = startTaskRE.match(line)
if m is not None:
taskNum = int(m.group(1))
elif line == '' and outfile != '':
#Save the SQL code to a file.
if sql:
if os.path.exists(outfile):
os.unlink(outfile)
with open(outfile, 'w') as fw:
fw.writelines(["%s" % sqlQ for sqlQ in sql])
print "%2d - %s" % (taskNum, outfile)
else:
print "%2d > No SQL (%s)" % (
taskNum, os.path.basename(outfile))
sql = []
outfile = ''
taskNum = -1
else:
#Acquire SQL code and filename
m = startSqlRE.match(line)
if m:
#Start assembling the SQL query.
tnum, sqlQ, lf = m.groups()
assert int(tnum) == taskNum
sql = [sqlQ.replace('""', '"')
+ ('\n' if lf is not None else '')]
continue
m = nextSqlRE.match(line)
if m:
#Continue assembling the SQL query
tnum, sqlQ, lf = m.groups()
assert int(tnum) == taskNum
sql.append(sqlQ.replace('""', '"')
+ ('\n' if lf is not None else ''))
continue
m = descripRE.match(line)
if m:
# Get a SQL output filename from the task's
# description. This always appears near the top of the
# task's definition.
tnum, outfile = m.groups()
assert int(tnum) == taskNum
outfile = invalidCharsRE.sub('_', outfile)
outfile = "%s%s.sql" % (outfolder, outfile)
continue
m = filenameRE.match(line)
if m:
# Get a SQL output filename from the task's output
# filename. This always appears near the bottom of the
# task's definition, so we overwrite the description if
# one was found earlier.
tnum, outfile = m.groups()
assert int(tnum) == taskNum
outfile = os.path.basename(outfile)
outfile = outExtRE.sub('', outfile)
outfile = "%s%s.sql" % (outfolder, outfile)
continue
print 'Done.'