0

現在、SQLServerといくつかのAccessDBファイル間でデータをインポート/エクスポートおよびアクセスする動的SSISパッケージを作成しています。(技術的になりたい場合はファイルをジェットします。)

とにかく、私のSSISパッケージにAccessファイルへの接続文字列がハードコードされている限り、テスト中はすべてが成功します。これは素晴らしく、うまく機能します。私はこれに満足しています。

この問題は、Access DBファイル(データが配置される宛先ファイル)への動的接続文字列を使用するようにVB.NETアプリケーションを変更したときに始まります。AccessDBファイルを「埋め込みリソース」としてアプリケーションに保存しています。

アクセス先ファイルの作成に使用するコードは次のとおりです。

    Public Sub CreateDestinationFile(ByVal path As String)

    'Create destination file from embedded project resources 
    Dim asm = System.Reflection.Assembly.GetExecutingAssembly()
    Dim objStream As System.IO.Stream = asm.GetManifestResourceStream("XXX.XXX_Export.mdb")
    Dim abytResource(objStream.Length) As [Byte]
    Dim intLength As Integer = objStream.Read(abytResource, 0, objStream.Length)
    Dim objFileStream = New FileStream(path + "XXX_Export.mdb", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)

    Try

        While intLength > 0
            'write filestream to create Access DB file
            objFileStream.Write(abytResource, 0, Convert.ToInt32(objStream.Length))
            intLength = objStream.Read(abytResource, 0, objStream.Length)
        End While

        'close the file stream
        objFileStream.Close()

    Catch ex As Exception
        'write error log here - ** omitted
    Finally
        asm = Nothing
        objStream = Nothing
        objFileStream = Nothing
    End Try

End Sub

これは正常に機能し、パスを指定する場所にアクセスDBファイルという正しい結果を生成します。これは、SSISパッケージにハードコードされた接続文字列がある場合にうまく機能します。

接続文字列を動的に変更し、同じ正確なテストを再実行すると、次のエラーが発生します。

「レコードを読み取ることができません。「MSysAccessObjects」に対する読み取り権限がありません。」

SSISパッケージの接続文字列の正規表現は次のようになります。

--SQL connection string
"Data Source=" + @[User::sourceDatabaseLocation] + ";User ID=" + @[User::sourceDBUserID] + ";Password=" + @[User::sourceDBPassword] + ";Initial Catalog=" + @[User::sourceDBName] + ";Provider=SQLOLEDB.1;Persist Security Info=True;Auto Translate=False;"

--Access connection string
"Data Source=" + @[User::destinationDatabasePath] + ";Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Password=;"

ローカルハードドライブ上のこのファイルに移動して開こうとすると、回復不能な状態にあることを確認し、修復するように求められますが、正常に実行されることはありません。

  1. ファイルの作成に関して何か見落としていませんか?(IO?)
  2. 組み込みリソースに関する何かを見落としていますか?(彼らは私にはかなり簡単に見えますが、おそらく私は何か明白なものを見落としていますか?)
  3. ファイルの状態が壊れていませんか?VS.NET IDEで、MSAccessを使用してローカルで開くことができます。
  4. このAccessファイルを再作成する価値はありますか?修復を回避するためにスキーマを新しいファイルにコピーできることを読みましたか?これはすごい危険に聞こえます!!

もともと、Access DBファイルのユーザーロールとそれを使おうとしているSSISに関して、これはパーミッションエラーだと思っていました。しかし、それだけではないと思います。ユーザーはAdminに設定されており、(理論的には)機能するはずです。

私はこれをハック/修正すると思います。現在、埋め込みリソースを使用しないようにしています。FileIO呼び出しを使用して、ファイルを目的のフォルダーに明示的に移動し、そこからデータを入力します。埋め込みリソースのdbファイルが機能しない理由を誰かが知っていますが、埋め込みリソースから作成されていない場合、同じファイルは機能しますか?リソースからファイルを作成するときに完了していないものはありますか?

フィードバックや提案は大歓迎です。ご不明な点も大歓迎です。ありがとうございました。

****更新/2009年7月18日:**

[CreateDestinationFile]ルーチンを変更して、埋め込みリソースを使用する代わりに、ファイル/IOの直接コピーを実行しました。

そのためのコードは次のとおりです。

        Dim sPath As String = My.Application.Info.DirectoryPath + "\databasenamehere.mdb"

        FileIO.FileSystem.CopyFile(sPath, path + "databasenamehere.mdb", True)

ファイルはプロジェクトから正しくコピーされていますが、次のエラーが発生します。

"OLE DBエラーが発生しました。エラーコード:0x80040E09。OLEDBレコードが使用可能です。ソース:" MicrosoftJETデータベースエンジン"Hresult:0x80040E09説明:"レコードを読み取ることができません。'TABLE_XXXXX'の読み取り権限はありません。」

これにより、SSISにはローカルのMSAccessDBを宛先ファイルとして使用するための適切なアクセス許可がないと思われます。

SSISパッケージに接続文字列をハードコーディングすると同じファイルが機能するため、これは私には奇妙です。ここで何が起こっているのですか?

接続文字列式でわかるように、ユーザーとして[Admin]があります。だからこれはうまくいくはずですよね?また、この問題のもう1つの考えられる原因は、これがAccess2003で作成されたレガシーMSAccess DBであり、ボックスでAccess2007を使用しているという事実です。ヘルプ?

4

2 に答える 2

0

これはひどく役立つ答えにはなりません。私はあなたが働いている環境では働いていないので、これを行う必要はありませんが、いくつかのことが頭に浮かびます。

ユーザーとしてadminを使用し、デフォルトのJetログオンである空白のパスワードを使用していますが、間違ったワークグループファイルを使用している可能性があります。接続文字列にワークグループファイル引数がない特定のメソッドによるJetファイルへの接続に問題がある他のStackOverflowポスターを思い出します。ODBC DSNを作成してから、それに接続しようとしましたか?DSNを使用すると、問題を改善できるようにワークグループファイルを指定できます。次に、結果の接続文字列をDSNなしの接続文字列に変換し、それをパラメーター化された接続文字列のモデルとして使用してみてください。

于 2009-07-16T20:36:16.453 に答える
0

この問題を解決するために、私は最初のプロジェクト収集中に提供されたテンプレートファイルを使用することになりました。

私が使用していた.mdbファイルは、多数のアプリケーションやテストプロジェクトに対して開発され、テストされていました。このファイルは初日から問題がありました。

このファイルに関する最初の問題は、サイズが80mbであったことです。データがほとんどないので、これは私には非常に奇妙でした。「圧縮して修復」する必要があることに気付いたとき、サイズは200kb未満に縮小されました。これは私を困惑させました。しかし、私はこのファイルをさらに開発するために使い続けました。

私はついに、このプロジェクトを継承したときに提供された元の.mdbファイルを自分の電子メールから掘り下げることにしました。この元の.mdbは、エクスポート先のテーブルにデータが含まれているため、まだ理想的ではありません。何千ものレコードを手動で削除する必要がありました。それを行うと、SSISパッケージは魔法のように機能しました。これで、SQLからAccessにデータを動的にエクスポートできるようになりました。

[app.config]構成ファイルによって提供される動的接続文字列を使用するSSISパッケージのVB.NET実行は次のとおりです。

Public Function ExecuteSSISExportPackage(ByVal parameterValue1 As String, ByVal destinationDatabasePath As String) As Integer

    Dim pkg As New Package
    Dim app As New Microsoft.SqlServer.Dts.Runtime.Application
    Dim pkgResults As DTSExecResult
    Dim result As Integer = 1 'defaults to failure
    Dim eventListener As New EventListener()

    'create SSIS variables for dynamic parameters, retrieved from the appSettings in the [app.config] file
    Dim SSISPackagePassword As String = ConfigurationManager.AppSettings.Item("SSISPackagePassword")
    Dim SSISExportPackagePath As String = ConfigurationManager.AppSettings.Item("SSISExportPackagePath")
    Dim SSISExportPackageServerName As String = ConfigurationManager.AppSettings.Item("SSISExportPackageServerName")
    Dim SSISExportPackageServerUserName As String = ConfigurationManager.AppSettings.Item("SSISExportPackageServerUserName")
    Dim SSISExportPackageServerPassword As String = ConfigurationManager.AppSettings.Item("SSISExportPackageServerPassword")
    Dim SSISExportPackageDestinationDBName As String = ConfigurationManager.AppSettings.Item("SSISExportPackageDestinationDBName")

    Try
        'set package password
        app.PackagePassword = SSISPackagePassword
        pkg.PackagePassword = SSISPackagePassword

        'load package from SQL server
        pkg = app.LoadFromSqlServer(SSISExportPackagePath, SSISExportPackageServerName, SSISExportPackageServerUserName, SSISExportPackageServerPassword, eventListener)

        'set package-level variables, to supply to the stored procedure parameters/sql calls in the SSIS Export package
        pkg.Variables("xxxx").Value = parameterValue1

        'set the package-level variable to supply the Access DB's (SSIS destination) file path
        Dim databaseName As String = ConfigurationManager.AppSettings.Item("XXXClientDatabaseName")
        pkg.Variables("destinationDatabasePath").Value = "C:\" + databaseName 

        'Dynamic SQL source connection string values
        pkg.Variables("sourceDatabaseLocation").Value = SSISExportPackageServerName
        pkg.Variables("sourceDBUserID").Value = SSISExportPackageServerUserName
        pkg.Variables("sourceDBName").Value = SSISExportPackageDestinationDBName
        pkg.Variables("sourceDBPassword").Value = SSISExportPackageServerPassword

        'Execute the Import SSIS package, add an eventListener object for SSIS reflection
        pkgResults = pkg.Execute(Nothing, Nothing, eventListener, Nothing, Nothing)

        'Package execution results
        Select Case pkgResults

            Case DTSExecResult.Success
                result = 0

            Case DTSExecResult.Failure
                result = 1

        End Select

    Catch ex As Exception

        'Log the exception error here - omitted

    Finally
        app = Nothing
        pkg = Nothing
    End Try

    Return result

End Function
于 2009-07-29T19:27:44.233 に答える