Проблема разрешения на чтение для .NET Embedded Resource - доступ к файлу БД и службам SSIS - PullRequest
0 голосов
/ 16 июля 2009

В настоящее время я создаю динамические пакеты служб SSIS, которые импортируют / экспортируют и получают доступ к данным между SQL Server и несколькими файлами БД Access. (Jet файлы, если вы хотите получить технический.)

В любом случае, все успешно во время тестирования, пока мои пакеты служб SSIS имеют жестко запрограммированные строки подключения к файлу Access. Это здорово и отлично работает. Я доволен этим.

Проблема теперь начинается, когда я изменяю свое приложение VB.NET на использование строк динамического соединения с файлом БД Access (конечный файл, в который будут помещены данные). У меня есть файл Access DB, хранящийся в моем приложении как «встроенный ресурс».

Вот код, который я использую для создания файла назначения доступа:

    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

Это прекрасно работает и дает правильные результаты, файл БД Access, где бы я ни указывал путь. Это хорошо работает, когда мои пакеты служб 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 и локально, с помощью MS Access.
  4. Стоит ли воссоздавать этот файл Access? Я читал, что вы можете скопировать схему в новый файл, чтобы избежать ремонта? Это звучит так рискованно !!

Первоначально я думал, что это ошибка разрешения, касающаяся роли пользователя в файле БД Access и попыток SSIS его использовать. Но я не думаю, что это так. Пользователь настроен на Admin и должен (теоретически) работать.

Я думаю, что для взлома / исправления я сейчас попытаюсь НЕ использовать встроенные ресурсы. Я буду использовать вызовы FileIO, чтобы явно переместить файл в нужную папку и заполнить его оттуда. Кто-нибудь знает, почему файл базы данных встроенного ресурса не будет работать, но тот же файл работает, если он не создан из встроенного ресурса? Есть ли что-то, что не завершается, когда я создаю свой файл из ресурса?

Любые отзывы и предложения приветствуются. Любые вопросы тоже приветствуются. Спасибо.

**** Обновление / 18.07.2009: **

Я изменил свою подпрограмму [CreateDestinationFile] для выполнения прямого копирования файла / ввода-вывода вместо использования встроенного ресурса.

Вот код для этого:

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

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

Файл правильно скопирован из проекта, но теперь я получаю эту ошибку:

"Произошла ошибка OLE DB. Код ошибки: 0x80040E09. Доступна запись OLE DB. Источник:" Microsoft JET Database Engine "Hresult: 0x80040E09 Описание:" Запись (и) не может быть прочитана; нет разрешения на чтение для TABLE_XXXXX. "

Это заставляет меня поверить, что SSIS не имеет надлежащих разрешений для использования моей локальной базы данных MS Access в качестве файла назначения.

Это странно для меня, потому что тот же файл работает, если я жестко закодировал строку подключения к нему в моем пакете служб SSIS. Что здесь происходит?

Как вы можете видеть в моих выражениях строки подключения, я имею [Admin] в качестве пользователя. Так что это должно работать, верно? Кроме того, еще одним возможным виновником этой проблемы является тот факт, что это устаревшая БД MS Access, созданная в Access 2003, и я использую Access 2007 на своем компьютере. Помощь

Ответы [ 2 ]

0 голосов
/ 29 июля 2009

Чтобы решить эту проблему, я использовал файл шаблона, который был предоставлен мне во время первоначального сбора проекта.

Файл .mdb, с которым я работал, был разработан и проверен многочисленными приложениями и тестовыми проектами. Этот файл был проблемным с самого первого дня.

Моя первая проблема с файлом состояла в том, что он был размером 80 МБ. Это было очень странно для меня, потому что в нем очень мало данных. Как только я понял, что мне нужно «сжать и починить», он уменьшил свой размер до 200 кб. Это сбило меня с толку. Но я продолжал использовать этот файл для дальнейшей разработки, которая, как я теперь понимаю, была большой нет-нет.

Я наконец решил выкопать из своих электронных писем оригинальный файл .mdb, предоставленный, когда я унаследовал этот проект. Этот оригинальный .mdb все еще не идеален, потому что он содержит данные в таблицах, в которые я экспортирую. Мне пришлось вручную удалить тысячи записей из него. Как только я это сделал, мой пакет служб SSIS волшебным образом работал. Теперь я могу динамически экспортировать данные из SQL в Access.

Вот мое VB.NET-выполнение пакета служб SSIS, в котором используются строки динамического соединения, предоставленные в файле конфигурации [app.config]:

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
0 голосов
/ 17 июля 2009

Это не будет очень полезным ответом, я не работаю в среде, в которой вы работаете, поэтому никогда не должен делать этого, но на ум приходит пара вещей.Используете admin в качестве пользователя и пустой пароль, который является входом в систему Jet по умолчанию, но, возможно, он использует неправильный файл рабочей группы.Я вспоминаю другие постеры StackOverflow, у которых были проблемы с подключением к файлам Jet определенными методами, у которых в строке подключения отсутствует аргумент файла рабочей группы.Вы пытались создать ODBC DSN, а затем пытаетесь подключиться к этому?DSN позволяет вам указать файл рабочей группы, чтобы устранить проблему.Затем можно попробовать преобразовать полученную строку подключения в строку подключения без DSN, а затем использовать ее в качестве модели для параметризованной строки подключения.

...