SSIS_Util: Tool zum Extrahieren von SQL aus der SSIS-Paketdatei (.dtsx)

Werfen wir einen Blick auf das Tool, das SQL aus der SSIS-Paketdatei extrahiert, die einfach für die SQL-Analyse während der jüngsten Arbeit mit SQL Server Integration Services (SSIS) erstellt wurde. Sie können die Ausführungsmethode, den Quellcode, die SQL-Datei und die CSV-Dateibeispiele der Ausgabeergebnisse überprüfen.

1. Übersicht über SSIS und SSIS_Util

1.1. SSIS-Übersicht

SSIS steht für „SQL Server Integration Services“ und ist in der Microsoft-Dokumentation wie folgt definiert.

Quelle: SQL Server-Integrationsdienste – SQL Server-Integrationsdienste (SSIS) | Microsoft-Docs

SSIS(SQL Server Integration Services) 개요
Übersicht über SQL Server Integration Services (SSIS).

SQL Server Integration Services ist die Plattform, die Sie zum Erstellen von Datenintegrations- und Datentransformationslösungen auf Unternehmensebene benötigen. Verwenden Sie Integration Services, um Dateien zu kopieren oder herunterzuladen, Data Warehouses zu laden, Daten zu bereinigen und zu minen und SQL Server-Objekte und -Daten zu verwalten, um komplexe Geschäftsprobleme zu lösen.

Integration Services kann Daten aus einer Vielzahl von Quellen extrahieren und transformieren, z. B. XML-Datendateien, Flatfiles und relationale Datenquellen, und sie dann in ein oder mehrere Ziele laden.

Integration Services umfasst einen umfangreichen Satz integrierter Vorgänge und Transformationen, grafische Tools zum Erstellen von Paketen und die Integration Services-Katalogdatenbank zum Speichern, Ausführen und Verwalten von Paketen.

Sie können grafische Integration Services-Tools verwenden, um Lösungen zu erstellen, ohne eine einzige Codezeile schreiben zu müssen. Sie können auch das umfangreiche Integration Services-Objektmodell programmieren, um Pakete programmgesteuert zu erstellen und benutzerdefinierte Tasks und andere Paketobjekte zu codieren.

Kurz zusammengefasst ist SSIS ein ETL-Tool, das Daten aus verschiedenen Quellen extrahiert, transformiert und lädt.

1.2. SSIS_Util-Übersicht

SSIS_Util ist ein Tool zum Extrahieren von SQL aus der SSIS-Paketdatei (.dtsx). Neben SQL werden auch Workflow-Informationen und DB ConnectionString extrahiert.

Die SSIS-Paketdatei (.dtsx) kann in Visual Studio geöffnet werden. Obwohl es einen Vorteil gibt, den Datenverarbeitungsvorgang visuell überprüfen zu können, ist es umständlich, das gesamte SQL zu durchsuchen oder die gesamten DB-Verbindungsinformationen zu überprüfen.

Es wurde erstellt, weil ich dachte, dass die Effizienz der Analyse verbessert werden könnte, indem die erforderlichen Informationen mit SSIS_Util in eine separate Datei extrahiert werden.

Der Quellcode wurde auf github hochgeladen.

https://github.com/DAToolset/SSIS_Util

2. Struktur der SSIS-Paketdatei (.dtsx).

Der Inhalt der dtsx-Datei ist in einer XML-Struktur definiert. Unter den geöffneten dtsx-Dateien werden einige Inhalte der folgenden Dateien extrahiert.

https://github.com/LearningTechStuff/SSIS-Tutorial/blob/master/Lesson%201.dtsx

<?xml version="1.0"?>
<DTS:Executable
  DTS:refId="Package" xmlns:DTS="www.microsoft.com/SqlServer/Dts"
  DTS:ExecutableType="SSIS.Package.3"
  DTS:CreatorName="REDWOOD\Barry"
  DTS:CreatorComputerName="REDWOOD"
  DTS:CreationDate="6/9/2012 4:03:57 PM"
  DTS:PackageType="5"
  DTS:VersionBuild="3"
  DTS:VersionGUID="{3A510DCF-C9DB-4039-9817-E408E5D2BACF}"
  DTS:LastModifiedProductVersion="11.0.2100.60"
  DTS:LocaleID="1033"
  DTS:ObjectName="Lesson 1"
  DTS:DTSID="{7691D130-E411-4B14-9676-A5DB6B8B4ADE}"
  DTS:CreationName="SSIS.Package.3">
  <DTS:Property
    DTS:Name="PackageFormatVersion">6</DTS:Property>
  <DTS:ConnectionManagers>
    <DTS:ConnectionManager
      DTS:refId="Package.ConnectionManagers[localhost.AdventureWorksDW2012]"
      DTS:ObjectName="localhost.AdventureWorksDW2012"
      DTS:DTSID="{F094926F-2384-48F7-9515-DB8ACC225303}"
      DTS:CreationName="OLEDB">
      <DTS:ObjectData>
        <DTS:ConnectionManager
          DTS:ConnectionString="Data Source=localhost;Initial Catalog=AdventureWorksDW2012;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;" />
      </DTS:ObjectData>
    </DTS:ConnectionManager>
    <DTS:ConnectionManager
      DTS:refId="Package.ConnectionManagers[Sample Flat File Source Data]"
      DTS:ObjectName="Sample Flat File Source Data"
      DTS:DTSID="{6DF5747F-57C2-4173-89B6-1A14A807DA3E}"
      DTS:CreationName="FLATFILE">
      <DTS:ObjectData>
        <DTS:ConnectionManager
          DTS:Format="Delimited"
          DTS:LocaleID="1033"
          DTS:HeaderRowDelimiter="_x000D__x000A_"
          DTS:RowDelimiter=""
          DTS:TextQualifier="_x003C_none_x003E_"
          DTS:CodePage="1252"
          DTS:ConnectionString="C:\Program Files\Microsoft SQL Server\110\Samples\Integration Services\Tutorial\Creating a Simple ETL Package\Sample Data\SampleCurrencyData.txt">
          <DTS:FlatFileColumns>
            <DTS:FlatFileColumn
              DTS:ColumnType="Delimited"
              DTS:ColumnDelimiter="_x0009_"
              DTS:DataType="4"
              DTS:TextQualified="True"
              DTS:ObjectName="AverageRate"
              DTS:DTSID="{786CE995-4B7C-41CE-BE81-37933271E018}"
              DTS:CreationName="" />
            <DTS:FlatFileColumn
              DTS:ColumnType="Delimited"
              DTS:ColumnDelimiter="_x0009_"
              DTS:MaximumWidth="3"
              DTS:DataType="130"
              DTS:TextQualified="True"
              DTS:ObjectName="CurrencyID"
              DTS:DTSID="{7E5616A8-02FD-49A7-ADEC-AB276D909B75}"
              DTS:CreationName="" />
            <DTS:FlatFileColumn
              DTS:ColumnType="Delimited"
              DTS:ColumnDelimiter="_x0009_"
              DTS:DataType="133"
              DTS:TextQualified="True"
              DTS:ObjectName="CurrencyDate"
              DTS:DTSID="{AF15821D-08F4-4FAA-B167-262FE448C298}"
              DTS:CreationName="" />
            <DTS:FlatFileColumn
              DTS:ColumnType="Delimited"
              DTS:ColumnDelimiter="_x000D__x000A_"
              DTS:DataType="4"
              DTS:TextQualified="True"
              DTS:ObjectName="EndOfDayRate"
              DTS:DTSID="{B9FC32CE-DE09-4626-B539-7E50A8469675}"
              DTS:CreationName="" />
          </DTS:FlatFileColumns>
        </DTS:ConnectionManager>
      </DTS:ObjectData>
    </DTS:ConnectionManager>
  </DTS:ConnectionManagers>
  <DTS:Variables />
  <DTS:Executables>
    <DTS:Executable
      DTS:refId="Package\Extract Sample Currency Data"
      DTS:ExecutableType="SSIS.Pipeline.3"
      DTS:TaskContact="Performs high-performance data extraction, transformation and loading;Microsoft Corporation; Microsoft SQL Server; (C) 2007 Microsoft Corporation; All Rights Reserved;http://www.microsoft.com/sql/support/default.asp;1"
      DTS:LocaleID="-1"
      DTS:ObjectName="Extract Sample Currency Data"
      DTS:DTSID="{E967823D-AA98-44CA-8B5D-E29585E4C0F0}"
      DTS:Description="Data Flow Task"
      DTS:CreationName="SSIS.Pipeline.3">
      <DTS:Variables />
      <DTS:ObjectData>
        <pipeline
          version="1">
          <components>
            <component
              refId="Package\Extract Sample Currency Data\Extract Sample Currency Data"
              name="Extract Sample Currency Data"
              componentClassID="{D23FD76B-F51D-420F-BBCB-19CBF6AC1AB4}"
              description="Flat File Source"
              localeId="1033"
              usesDispositions="true"
              version="1"
              contactInfo="Flat File Source;Microsoft Corporation; Microsoft SQL Server; (C) Microsoft Corporation; All Rights Reserved; http://www.microsoft.com/sql/support;1">
              <properties>
                <property
                  name="RetainNulls"
                  dataType="System.Boolean"
                  description="Specifies whether zero-length columns are treated as null.">false</property>
                <property
                  name="FileNameColumnName"
                  dataType="System.String"
                  description="Specifies the name of an output column containing the file name. If no name is specified, no output column containing the file name will be generated."></property>
              </properties>
              <connections>
...

Den genauen Aufbau der dtsx-Datei finden Sie auf der folgenden Seite.

https://docs.microsoft.com/en-us/openspecs/sql_data_portability/ms-dtsx/235600e9-0c13-4b5b-a388-aa3c65aec1dd

3. SSIS_Util-Python-Code

Den Quellcode finden Sie unter folgendem Pfad.

https://github.com/DAToolset/SSIS_Util/blob/main/ssis_util.py

3.1. Installieren Sie die erforderlichen Pakete

Um diesen Code auszuführen, müssen Sie das lxml-Paket als XML-Parser installieren.

pip lxml installieren

3.2. SQL extrahieren: So führen Sie SSIS_Util aus

python ssis_util.py --in_path <dtdx file path> --out_path <output sql file path>

Der gesamte Pfad unter dem in in_path angegebenen Pfad wird rekursiv durchsucht, um die .dtsx-Datei zu finden, und SQL-Inhalte werden aus der Datei extrahiert und in out_path gespeichert.

3.3. SQL-Extraktion des vollständigen Quellcodes

Der vollständige Quellcode ist unten eingefügt.

from lxml import etree
import os
import datetime
import csv
import argparse

# region XML Tag definition
pfx = '{www.microsoft.com/'
tag_Executable = pfx + 'SqlServer/Dts}Executable'
tag_ObjectName = pfx + 'SqlServer/Dts}ObjectName'
atr_refId = pfx + 'SqlServer/Dts}refId'
tag_Objectdata = pfx + 'SqlServer/Dts}ObjectData'
tag_SqlTaskData = pfx + 'sqlserver/dts/tasks/sqltask}SqlTaskData'
atr_ConnectionID = pfx + 'sqlserver/dts/tasks/sqltask}Connection'
atr_SqlStatementSource = pfx + 'sqlserver/dts/tasks/sqltask}SqlStatementSource'
atr_Disabled = pfx + 'SqlServer/Dts}Disabled'

# precedence
tag_PrecedenceConstraint = pfx + 'SqlServer/Dts}PrecedenceConstraint'
tag_From = pfx + 'SqlServer/Dts}From'
tag_To = pfx + 'SqlServer/Dts}To'

# connection
tag_ConnectionManager = pfx + 'SqlServer/Dts}ConnectionManager'
tag_CreationName = pfx + 'SqlServer/Dts}CreationName'
atr_ConnectionString = pfx + 'SqlServer/Dts}ConnectionString'
atr_DTSID = pfx + 'SqlServer/Dts}DTSID'

# variable
tag_Variable = pfx + 'SqlServer/Dts}Variable'
tag_Expression = pfx + 'SqlServer/Dts}Expression'
tag_Namespace = pfx + 'SqlServer/Dts}Namespace'
# endregion


def get_sql_using_xpath(file_name) -> (str, dict):

    tree = etree.parse(file_name)
    root = tree.getroot()

    con_dic = {}  # Key: ConnectionName , Value: ConnectionProperty
    con_id_dic = {}  # Key: ConnectionID , Value: ConnectionName
    con_cnt = 0
    var_dic = {}  # Key: "NameSpace::ObjectName", Value: Expression, etc...

    for ele in root.findall(f'.//{tag_ConnectionManager}[@{atr_DTSID}]'):  # extract connection list
        con_cnt += 1
        con_id = ele.attrib[atr_DTSID]
        con_name = ele.attrib[tag_ObjectName]
        cre_name = ele.attrib[tag_CreationName]
        con_str = ""
        con_ele = ele.find(f'.//{tag_Objectdata}/{tag_ConnectionManager}')
        if con_ele is not None and atr_ConnectionString in con_ele.attrib:
            con_str = con_ele.attrib[atr_ConnectionString]
        con_id_dic[con_id] = con_name
        con_dic[con_name] = f'{con_cnt}. {con_name}\n  - CreationName:{cre_name}\n  - ConnectionString:[{con_str}]'
    con_text = '\n\n'.join(f'{v}' for k, v in con_dic.items())

    for ele in root.findall(f'.//{tag_Variable}[@{tag_Expression}]'):  # extract variable list
        var_name = ele.attrib[tag_Namespace] + "::" + ele.attrib[tag_ObjectName]  # Key: "NameSpace::ObjectName"
        var_val = ele.attrib[tag_Expression]
        var_dic[var_name] = var_val

    sql_str = ""
    for ele in root.findall(f'.//{tag_Executable}/{tag_Objectdata}/{tag_SqlTaskData}/../..'):  # extract SQL list
        if atr_refId not in ele.attrib:
            continue
        ref_id = ele.attrib[atr_refId]
        sql_ele = ele.find(f'.//{tag_Objectdata}/{tag_SqlTaskData}[@{atr_SqlStatementSource}]')
        if is_disabled(ele):  # exclude Disabled task(also ancestor Elements)
            continue
        tsk_sql_str = ""
        tsk_con_name = ""
        tsk_con_str = ""
        if sql_ele is not None:
            tsk_con_id = sql_ele.attrib[atr_ConnectionID]
            tsk_con_name = con_id_dic[tsk_con_id]
            tsk_con_str = con_dic[tsk_con_name]
            tsk_sql_str = sql_ele.attrib[atr_SqlStatementSource]
            sql_str += f'/* [Control Flow(제어 흐름) TaskName: {ref_id}]\n   [Connection: {tsk_con_str}]\n*/\n{tsk_sql_str}'
            sql_str += get_line_separator()

    data_flow_str = ""
    for ele in root.findall(f'.//pipeline/components/component[@refId]'):  # extract data flow list
        if is_disabled(ele):  # exclude Disabled task(also ancestor Elements)
            continue
        ref_id = ele.attrib['refId']
        sql_cmd_var_str = ""; sql_cmd_str = ""; open_rowset_str = ""
        sql_cmd_var_ele = ele.find(f'.//property[@name="SqlCommandVariable"]')
        if sql_cmd_var_ele is not None:
            sql_cmd_var_str = sql_cmd_var_ele.text
        sql_cmd_ele = ele.find(f'.//property[@name="SqlCommand"]')
        if sql_cmd_ele is not None:
            sql_cmd_str = sql_cmd_ele.text
        open_rowset_ele = ele.find(f'.//property[@name="OpenRowset"]')
        if open_rowset_ele is not None and open_rowset_ele.text is not None:
            open_rowset_str = "OpenRowset: " + open_rowset_ele.text
        str_list = [sql_cmd_var_str, sql_cmd_str, open_rowset_str]
        try:
            data_flow_val = next(s for s in str_list if s)
        except:
            data_flow_val = ''

        con_str = ''
        con_ele = ele.find(f'.//connections/connection[@connectionManagerID]')
        if con_ele is not None:
            con_str = con_ele.attrib['connectionManagerID']
        data_flow_str += f'/* [Data Flow(데이터 흐름) TaskName: {ref_id}]\n   [Connection: {con_str}] */\n{data_flow_val}'
        data_flow_str += get_line_separator()

    prd_text = ""
    for ele in root.findall(f'.//{tag_PrecedenceConstraint}[@{tag_From}]'):  # make precedence string
        prd_from = ele.attrib[tag_From]
        prd_to = ele.attrib[tag_To]
        prd_text += f'[{prd_from}] --> [{prd_to}]\n'

    result_str = f"""/* Precedence Constraint(실행 순서)
{prd_text}*/
{get_line_separator()}
/* Connections(연결 정보)
{con_text}
*/
{get_line_separator()}
{data_flow_str}
{get_line_separator()}
{sql_str}"""

    return result_str, con_dic


def get_current_datetime() -> str:
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")


def get_line_separator() -> str:
    return f'\n\n/*{"*" * 100}*/\n\n'


def is_disabled(ele) -> bool:
    """check if the element has 'Disabled' attribute and it's value is 'True', and check parent element"""
    if atr_Disabled in ele.attrib and ele.attrib[atr_Disabled].lower() == "true":
        return True
    else:
        pele = ele.find('..')
        if pele is None:
            return False
        else:
            return is_disabled(pele)


def main():
    parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('--in_path', required=True, type=str,
                        help='input path with dtsx files')
    parser.add_argument('--out_path', required=True, type=str,
                        help='output path with extracted sql files from dtsx files')
    args = parser.parse_args()
    in_path = os.path.abspath(args.in_path)
    out_path = os.path.abspath(args.out_path)
    file_list = []
    print(f'[{get_current_datetime()}] Start Get File List...')
    in_abspath = os.path.abspath(in_path)  # os.path.abspath('.') + '\\test_files'
    file_types = ('.dtsx',)
    for root, dir, files in os.walk(in_abspath):
        for file in sorted(files):
            # exclude
            if file.startswith('~'):
                continue
            # include
            if file.endswith(file_types):
                file_list.append(root + '\\' + file)

    print(f'[{get_current_datetime()}] Finish Get File List. ({len(file_list)} files)')

    print(f'[{get_current_datetime()}] Start Extract File Contents...')
    con_list = []
    for dtsx_file in file_list:
        print(dtsx_file)
        sql_file = dtsx_file.replace(in_path, out_path) + ".sql"
        sql_file_dir = os.path.dirname(sql_file)
        os.makedirs(name=sql_file_dir, exist_ok=True)
        result_str, con_dic = get_sql_using_xpath(dtsx_file)
        tmp_list = []
        for k, v in con_dic.items():
            tmp_list.append([dtsx_file, sql_file, k, v])
        if len(tmp_list) > 0:
            con_list.append(tmp_list)
        with open(sql_file, "w", encoding="utf8") as file:
            file.write(result_str)

    csv_file = out_path + "\\con_sql.csv"
    with open(csv_file, 'w', newline='', encoding='ansi') as file:
        writer = csv.writer(file)
        writer.writerow(["dtsx_file", "sql_file", "connection name", "connection property"])
        # writer.writerow(con_list)
        for con in con_list:
            for con2 in con:
                writer.writerow(con2)

    print(f'[{get_current_datetime()}] Finish Extract File Contents. ({len(file_list)} files)')


if __name__ == '__main__':
    main()

# sample dtsx file: https://github.com/LearningTechStuff/SSIS-Tutorial
  • Zeile 7: XML mit NameSpace muss den entsprechenden NameSpace in Tags und Attributen angeben. Wenn der NameSpace wiederholt als String geschrieben wird, verschlechtert sich die Lesbarkeit des Codes, also vorher als separate Variable deklarieren.
  • Zeile 38: Parsen der Eingabedatei mit dem lxml-Paket.
  • Zeile 46: Durchlaufen Sie Verbindungsinformationen mit XPath-Syntax.
  • Zeile 56: Verbindungsinformationen in einem separaten Wörterbuch speichern. Der Schlüssel ist der Verbindungsname und der Wert ist die Verbindungszeichenfolge. Diese Informationen werden verwendet, um die Verbindungszeichenfolge als Verbindungsname der Aufgabe in Zeile 78 zu erhalten.
  • Zeilen 70 und 85: Wenn einer der Vorgängerknoten, einschließlich seines eigenen Knotens, deaktiviert ist, extrahieren Sie sie nicht. Dieser Code wurde hinzugefügt, um das Extrahieren unnötiger Informationen zu vermeiden. Sie können diesen Code auskommentieren, um die vollständigen Informationen zu extrahieren.
  • Zeile 112: Extrahieren Sie die Task-Vorgänger/Sequenz-Beziehung.
  • Zeilen 117-126: Eine Struktur zum Speichern der gesamten extrahierten Informationen wird zusammengestellt.
  • Zeile 139: Dies ist die Funktion, die in den Zeilen 70 und 85 aufgerufen wird. Es wird rekursiv aufgerufen, um den Vorfahren eine Ebene höher zu bestimmen.
  • Zeile 188: Speichern Sie das in den Zeilen 117 bis 126 erstellte Extraktionsergebnis als .sql-Datei.
  • Zeilen 192~198: Sammeln Sie alle Verbindungsinformationen, die in Zeile 56 erstellt wurden, und speichern Sie sie als separate CSV-Datei.

4. SSIS_Util-Ausgabebeispiel

4.1. Beispiel für eine SQL-Extraktionsergebnisdatei

/* Precedence Constraint(실행 순서)
[Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task1] --> [Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task2]
[Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task2] --> [Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task3]
[Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task3] --> [Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task4]
[Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task4] --> [Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task5]
*/


/******************************************************************************************************/


/* Connections(연결 정보)
1. key 캐시연결
  - CreationName:CACHE
  - ConnectionString:[]

2. 10.x.x.1.admin.admin
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;User ID=admin;Initial Catalog=admin;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]

3. 10.x.x.1.db3.admin
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;User ID=admin;Initial Catalog=db3;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]

4. 10.x.x.1.db3.admin
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;Initial Catalog=db4;Provider=SQLNCLI11;Integrated Security=SSPI;]

5. localhost.db2
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.2;User ID=admin;Initial Catalog=db2;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]

6. localhost.db1
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.3;User ID=admin;Initial Catalog=db1;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]
*/


/******************************************************************************************************/

/* [Data Flow(데이터 흐름) TaskName: Package\update\task4 Source]
   [Connection: Package.ConnectionManagers[10.x.x.4.db6.admin]] */
select ...
  from ...

/******************************************************************************************************/

/* [Data Flow(데이터 흐름) TaskName: Package\update\task4 Target]
   [Connection: Package.ConnectionManagers[localhost.db1]] */
OpenRowset: [dbo].[table1]

/******************************************************************************************************/


/* [Control Flow(제어 흐름) TaskName: Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task1]
   [Connection: 6. localhost.db1
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.3;User ID=admin;Initial Catalog=db1;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]]
*/
delete from ... where dt = @dt

insert ...
(...)
select
...
from (
    select 
        ...
    from #tempp a
        inner join ... b
            on ...
    where (...)
) t
where ...

/******************************************************************************************************/

/* [Control Flow(제어 흐름) TaskName: Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task2]
   [Connection: 5. localhost.db2
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.2;User ID=admin;Initial Catalog=db2;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]]
*/
if object_id('tempdb.dbo.#tempp') is not null
    drop table #tempp

select
     ...
  into #tempp
  from ... a
 where dt = @dt
 group by ...

merge ... a
    using (...) b
        on ...
when not matched then 
    insert(...)
    values(...);

/******************************************************************************************************/

/* [Control Flow(제어 흐름) TaskName: Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task3]
   [Connection: 3. localhost.db3
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;User ID=admin;Initial Catalog=db3;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]]
*/

update b
   set ...
  from ... a
       inner join ... b
        on ...
where ...

/******************************************************************************************************/

/* [Control Flow(제어 흐름) TaskName: Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task4]
   [Connection: 4. localhost.db4
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;Initial Catalog=db4;Provider=SQLNCLI11;Integrated Security=SSPI;]]
*/
update b
   set ...
  from ... a
       inner join ... b
        on ...
where ...

/******************************************************************************************************/

/* [Control Flow(제어 흐름) TaskName: Package\Foreach 루프 컨테이너\시퀀스 컨테이너\task5]
   [Connection: 2. localhost.admin
  - CreationName:OLEDB
  - ConnectionString:[Data Source=10.x.x.1;User ID=admin;Initial Catalog=admin;Provider=SQLNCLI11;Persist Security Info=True;Auto Translate=False;]]
*/
if object_id('tempdb.dbo.#tempm') is not null
    drop table #tempm

select
      ...
  into #tempm
  from a
 where a.dt = @dt

merge ... a
using (...) b
   on ...
  and ...
when not matched then
    insert (...)
    values (...);

/******************************************************************************************************/

4.2. csv-Datei Beispiel

Die CSV-Datei enthält dtsx_file, sql_file, Verbindungsname und Informationen zu Verbindungseigenschaften.

SSIS_Util 출력 csv 파일 예시
Beispiel einer SSIS_Util-Ausgabe einer CSV-Datei

Es wird erwartet, dass es nützlich ist, wenn eine Analyse aus einer Gesamtperspektive in einer Umgebung erforderlich ist, in der SSIS verwendet wird.

Wenn Sie Fehler oder Verbesserungen im Quellcode haben, hinterlassen Sie diese bitte in den Kommentaren.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

de_DEDeutsch