在 SSIS 中使用 C# 脚本获取带时间戳的 CSV 文件名

Get Filename of Timestamped CSV using C# Script in SSIS

我正在开发一个 SSIS 包,该包将 CSV 文件中的数据加载到 SQL 服务器中的临时 table。 CSV 文件将采用以下格式:

FILENAME_YYYYMMDD_HHMMSS.csv

YYMMDD 部分将始终对应于昨天的日期,但 HHMMSS 部分将根据 CSV 文件的创建时间而有所不同。

有没有办法在 SSIS 中使用脚本组件来执行以下操作:

  1. 检查是否有昨天写入的文件(YYYYMMDD = 昨天的日期)
  2. 如果是这样,将完整的文件名存储到一个变量

我认为这是对其他答案的应用

  • YYYYMMDD 模式

  • Foreach 模式 How to import text files with the same name and schema but different directories into database?

第一个 link 展示了我们如何使用表达式构建 YYYYMMDD 字符串。您需要昨天的日期,所以我会通过应用 dateadd("dd", -1, @[System::StartTime) 3 次来扩展该答案,或者我会添加第三个变量 Yesterday 然后引用它。在这个答案中,我将添加 Yesterday 变量并使用它。

第二个 link 涉及使用 Foreach(文件)枚举器。循环作为 FileSpec 过滤器。我们将使用一个变量来保存这个值,并且该变量将应用一个表达式

"FILENAME_" + @[User::YYYYMMDD]+ "_*.csv"

这是我们的硬编码文件名,其中包含我们在第一步中创建的变量,然后是一个星号来处理可变时间组件。

当 foreach 循环运行时,它将把完全限定的路径名​​填充到一个名为 CurrentFileName

的变量中

我们使用 that 作为平面文件连接管理器上的表达式,以便在导入之前将其指向正确的文件。

看起来很多,但玩过之后,应该还不错。

比姆

创建此包的 biml 几乎与 post 在第二个 linked post 上创建的相同。查看更改的地方是 FileSpec 的表达式。

你如何使用它?

  • 将文件放在 C:\ssisdata\so\TEST1306\sample1.txt(或将所有对它的引用修复到其他地方)

文件应如下所示

ID,value
1,text here
  • 安装 BIDS Helper 免费附加组件以改善您的 BI 生活
  • 在一个IS项目中,右击该项目并添加一个新的biml文件
  • 双击BimlScript.biml并添加以下内容替换所有内容
  • 保存
  • 右键单击 BimlScript.biml 文件并 select 生成 SSIS 包

利润

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <!-- Create a basic flat file source definition -->
    <FileFormats>
        <FlatFileFormat
            Name="FFFSrc"
            CodePage="1252"
            RowDelimiter="CRLF"
            IsUnicode="false"
            FlatFileType="Delimited"
            ColumnNamesInFirstDataRow="true"
        >
            <Columns>
                <Column
                    Name="ID"
                    DataType="Int32"
                    Delimiter=","
                    ColumnType="Delimited"
                />
                <Column
                    Name="value"
                    DataType="AnsiString"
                    Delimiter="CRLF"
                    InputLength="20"
                    MaximumWidth="20"
                    Length="20"
                    CodePage="1252"
                    ColumnType="Delimited"
                    />
            </Columns>
        </FlatFileFormat>
    </FileFormats>

    <!-- Create a connection that uses the flat file format defined above-->
    <Connections>
        <FlatFileConnection
            Name="FFSrc"
            FileFormat="FFFSrc"
            FilePath="C:\ssisdata\so\TEST1306\sample1.txt"
            DelayValidation="true"
        />
    </Connections>

    <!-- Create a package to illustrate how to apply an expression on the Connection Manager -->
    <Packages>
        <Package
            Name="so_29480267"
            ConstraintMode="Linear"
        >
            <Connections>
                <Connection ConnectionName="tempdb"/>
                <Connection ConnectionName="FFSrc">
                    <Expressions>
                        <!-- Assign a variable to the ConnectionString property. 
                        The syntax for this is ConnectionManagerName.Property -->
                        <Expression PropertyName="FFSrc.ConnectionString">@[User::CurrentFileName]</Expression>
                    </Expressions>
                </Connection>
            </Connections>

            <!-- Create a single variable that points to the current file -->
            <Variables>
                <Variable Name="CurrentFileName" DataType="String">C:\ssisdata\so\TEST1306\sample1.txt</Variable>
                <Variable Name="Yesterday" DataType="DateTime" EvaluateAsExpression="true">DATEADD("dd", -1, @[System::StartTime])</Variable>
                <Variable Name="YYYYMMDD" DataType="String" EvaluateAsExpression="true">(DT_WSTR, 4)YEAR(@[User::Yesterday]) 
+ RIGHT("0" + (DT_WSTR, 2) MONTH(@[User::Yesterday]), 2) 
+ RIGHT("0" + (DT_WSTR, 2) DAY(@[User::Yesterday]), 2)</Variable>
                <Variable Name="FileMask" DataType="String" EvaluateAsExpression="true">"FILENAME_" + @[User::YYYYMMDD]+ "_*.csv"</Variable>
                <Variable Name="SourceFolder" DataType="String">C:\ssisdata\so\TEST</Variable>
                <Variable Name="RowCountInput" DataType="Int32">0</Variable>
                <Variable Name="TargetTable" DataType="String">[dbo].[so_29480267]</Variable>
            </Variables>

            <!-- Add a foreach file enumerator. Use the above -->
            <Tasks>

                <ForEachFileLoop
                    Name="FELC Consume files"
                    FileSpecification="*.csv"
                    ProcessSubfolders="true"
                    RetrieveFileNameFormat="FullyQualified"
                    Folder="C:\"
                    ConstraintMode="Linear"
                >
                    <!-- Define the expressions to make the input folder and the file mask 
                    driven by variable values -->
                    <Expressions>
                        <Expression PropertyName="Directory">@[User::SourceFolder]</Expression>
                        <Expression PropertyName="FileSpec">@[User::FileMask]</Expression>
                    </Expressions>
                    <VariableMappings>
                        <!-- Notice that we use the convention of User.Variable name here -->
                        <VariableMapping
                            Name="0"
                            VariableName="User.CurrentFileName"
                        />
                    </VariableMappings>
                    <Tasks>
                        <Dataflow Name="DFT Import file" DelayValidation="true">
                            <Transformations>
                                <FlatFileSource Name="FFS Sample" ConnectionName="FFSrc"/>
                                <RowCount Name="RC Source" VariableName="User.RowCountInput"/>
                            </Transformations>
                        </Dataflow>
                    </Tasks>
                </ForEachFileLoop>
            </Tasks>
        </Package>
    </Packages>
</Biml>