0

SSISスクリプトタスクエラー

ディレクトリとファイル名を含むテーブルがあり、テキストファイルとの間の接続文字列として使用します。

foreachループを使用して、変数に割り当てられたテーブルから値を取得します。ソースDir +ソースファイル名の組み合わせである式変数があり、ファイルがSSISにのみ存在するかどうかを確認する他の方法がないためです。スクリプトタスクで、私はそうしました

public void chkIfExist()
{
    if (File.Exists(Dts.Variables["User::srcFull"].Value.ToString()))
    {
        Dts.TaskResult = (int)ScriptResults.Success;    
    }
    else
    {
        Dts.TaskResult = (int)ScriptResults.Failure;
    }
}

注:User::srcFull検証可能な式です@[User::srcPath] + @[User::srcFile]

クラッシュし続けたので、実行時にスクリプトにウォッチを配置するDts.Variables["User::srcFull"].Value.ToString()と、関数の評価がタイムアウトになりました。

私は何が起こっているのかを理解しようとしましたが、値はrawsetからのものであるため、スクリプトコンポーネントはそれを評価できないという結論に達しました...

スクリプトタスク内で式が正しく評価されないのはなぜですか?この問題を解決する方法はありますか?

4

3 に答える 3

2

可能なオプション:

Execute SQL Taskを使用する代わりに、を使用してレコードセットをフェッチできますData Flow Task

例を示すSSIS2012パッケージ:

dbo.FileNamesデータデータベースにいくつかのサンプル行を含む名前付きのテーブルがあると仮定します。

テーブルスクリプトを作成して入力します。

CREATE TABLE dbo.FileNames(
    srcPath nvarchar(255) NULL,
    srcName nvarchar(60) NULL
);

GO

INSERT INTO dbo.FileNames (srcPath, srcName) VALUES
        ('C:\temp', 'File_1.txt')
    ,   ('C:\temp', 'File_2.txt')
    ,   ('C:\temp', 'File_3.txt')
    ;
GO

以下に示すように、[制御フロー]タブを構成します。を配置しExecute SQL Taskてテーブルデータを読み取り、オブジェクトデータ型に格納します。Foreach Loop ContainerSQL実行タスクの後にaを配置し、Foreachループコンテナ内にaを配置Script Taskます

[制御フロー]タブ

次の変数を作成します。パスに末尾の円記号がない場合は、それに応じてパスとファイル名の間に追加されるよう@[User::srcPath] + "\\" + @[User::srcFile]に、変数で式を使用することをお勧めします。srcFull

Variable name  Scope         Data type  Expression
-------------- ------------- ---------- -----------
FileNames      SO_15072939   Object
srcFile        SO_15072939   String
srcFull        SO_15072939   String     @[User::srcPath] + "\\" + @[User::srcFile]
srcPath        SO_15072939   String

変数

SQL実行タスクを構成して、接続マネージャーに対して以下のクエリを実行し、ファイルパスと名前の情報を読み取ります。

SELECT srcPath, srcName FROM dbo.FileNames

SQLタスクの実行-一般

FileNamesクエリによって返される結果セットは、データ型の変数に格納する必要がありますObject

SQLタスクの実行-結果セット

を使用しForeach Loop Containerて変数FileNamesを読み取るようにを構成しForeach ADO Enumeratorます。

Foreachループコンテナ-コレクション

結果セットがループスルーされるときに列値を格納するように2つのパッケージ変数を構成します。

Foreachループコンテナ-変数マッピング

変数を読み取るようにスクリプトタスクエディタを構成しますsrcFull

スクリプトタスクエディタ

以下のコードをスクリプトタスクに追加します。

SSIS 2008以降のC#でのスクリプトタスクコード:

#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.IO;
#endregion

namespace ST_f1d7b6ab42e24ad5b5531684ecdcae87
{
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {
        public void Main()
        {
            string filePath = Dts.Variables["User::srcFull"].Value.ToString();

            MessageBox.Show(filePath);

            Dts.TaskResult = File.Exists(filePath)
                                ? (int)ScriptResults.Success
                                : (int)ScriptResults.Failure;
        }

        #region ScriptResults declaration
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion
    }
}

スクリプトタスクコード

パッケージを実行すると、変数値がに表示されMessageBoxます。

パッケージの実行

C:\temp\File_1.txtパスが存在しないため、このサンプルではパッケージが失敗します。

パッケージの失敗

OPのコメントへの回答:

私はあなたがここに示していることをしました、私の問題は、User :: srcFile変数がReadWriteVariablesとしてスクリプトタスクに追加されているので(同じスクリプトでいくつかのことをする必要があるため)、ちょっとロックされているようですしたがって、定義が@ [User :: srcPath] + @ [User::srcFile]であるUser::srcFull変数は評価できません。

スクリプトタスクエディタで変数srcFullをからReadOnlyVariablesに変更しましたが、式は引き続き正しく評価されました。サンプル入力でこれらの3つのファイルを作成し、パッケージはメッセージボックスに各パスを正しく表示し、正常に実行を完了しました。ReadWriteVariables

スクリプトタスクForeachループコンテナの両方が同じ変数を更新しようとしているため、変数srcPathとスクリプトタスクエディタsrcFileのセクションに追加すると、競合が発生するだけです。ReadWriteVariables

于 2013-02-25T18:21:06.163 に答える
1

手始めに、File.Exists:を呼び出す前に、3つの変数すべてを使用して情報イベントを発生させます。

public void chkIfExist()
{
    bool fireAgain = true;
    Dts.Events.FireInformation(0,
        "MyScriptTask",
        String.Format("srcPath is \"{0}\"", Dts.Variables["User::srcPath"].Value),
        "",
        0,
        ref fireAgain);
    Dts.Events.FireInformation(0,
        "MyScriptTask",
        String.Format("srcFile is \"{0}\"", Dts.Variables["User::srcFile"].Value),
        "",
        0,
        ref fireAgain);
    Dts.Events.FireInformation(0,
        "MyScriptTask",
        String.Format("srcFull is \"{0}\"", Dts.Variables["User::srcFull"].Value),
        "",
        0,
        ref fireAgain);
    string fullPath = Dts.Variables["User::srcFull"].Value.ToString();
    if (System.IO.File.Exists(fullPath))
    {
        Dts.TaskResult = (int)ScriptResults.Success;
    }
    else
    {
        Dts.TaskResult = (int)ScriptResults.Failure;
    }
}

ここでの目的は、失敗したレコードがどのように見えるかをよりよく理解することです。

于 2013-02-25T18:19:22.563 に答える
-1

ReadOnlyVariablesscriptTaskが変数を評価するには、セクション内のすべての変数を渡す必要があります。あなたの場合、ReadOnlyVariablesはsrcPath, srcFile, srcFull

于 2013-08-06T18:46:26.783 に答える