如何从DTS对象导出SQL语句?

时间:2008-10-27 17:25:15

标签: sql sql-server dts

我正在运行SQL Server 2000,我需要从所有DTS对象中导出SQL语句,以便在需要时可以解析它们并将其放入Wiki文档中。

有办法吗?

可能会将每个DTS对象转储到一个文本文件中,其中对象名称为文件名,包含进程名称和将其作为文件头提取的日期。

感谢。

3 个答案:

答案 0 :(得分:2)

有一个带有DTS包对象模型的API。您可以通过此获取SQL文本。联机丛书文档在某种程度上描述了这一点Here.您可以通过Saving the DTS package to a Visual BASIC file获取对象模型用法的示例,并查看VB文件对对象模型的作用。

答案 1 :(得分:1)

如果你想保存一些工作并且不介意花几块钱,那么tool可以完整记录你的DTS包。它也输出到XML,因此获取这些SQL语句应该相对容易。

答案 2 :(得分:1)

我有一个Python 2.6脚本(很容易移植到Python 2.5),它从已保存为Visual Basic代码的DTS包中的任务转储SQL。

请参阅ConcernedOfTunbridgeWells的帖子,了解如何将DTS包保存到VB文件。保存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.'