我目前正在创建动态 SSIS 包,用于在 SQL Server 和多个 Access DB 文件之间导入/导出和访问数据。(如果您想获得技术知识,请使用 Jet 文件。)
无论如何,只要我的 SSIS 包具有到 Access 文件的硬编码连接字符串,在测试期间一切都会成功。这很棒,而且效果很好。我对此很满意。
现在,当我更改我的 VB.NET 应用程序以使用动态连接字符串到 Access DB 文件(目标文件,数据将被放置的位置)时,问题就开始了。我将 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 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=;"
当我导航到本地硬盘驱动器上的该文件并尝试打开它时,它提示我它处于不可恢复的状态并修复它,但它从未成功过。
- 我是否忽略了有关文件创建的某些内容?(IO?)
- 我是否忽略了有关嵌入式资源的某些内容?(它们对我来说似乎很直接,但也许我忽略了一些明显的东西?)
- 我的文件状态是否已损坏?我可以使用 MS Access 在 VS.NET IDE 和本地打开它。
- 是否值得重新创建此 Access 文件?我读过您可以将架构复制到新文件以避免修复?这听起来太冒险了!!
最初我认为这是一个权限错误,关于 Access DB 文件的用户角色和 SSIS 试图使用它。但我不认为是这样。用户设置为管理员并且应该(理论上)工作。
我认为要破解/修复此问题,我目前将尝试不使用嵌入式资源。我将使用 FileIO 调用将文件显式移动到我想要的文件夹并从那里填充它。有谁知道为什么嵌入式资源数据库文件不起作用,但是当不是从嵌入式资源生成时,同一个文件确实起作用?当我从资源创建文件时,是否有未完成的内容?
非常感谢任何反馈或建议。也欢迎任何问题。谢谢你。
**** 更新/07/18/2009:**
我修改了我的 [CreateDestinationFile] 例程以执行直接文件/IO 复制,而不是使用嵌入式资源。
这是代码:
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 数据库引擎”Hresult:0x80040E09 描述:“无法读取记录;'TABLE_XXXXX' 没有读取权限。”
这使我相信 SSIS 没有适当的权限将我的本地 MS Access DB 用作目标文件。
这对我来说很奇怪,因为如果我在我的 SSIS 包中将连接字符串硬编码到它,则相同的文件可以工作。这里发生了什么?
正如您在我的连接字符串表达式中看到的那样,我有 [Admin] 作为用户。所以这应该有效,对吧?此外,这个问题的另一个可能的罪魁祸首是这是在 Access 2003 中创建的旧版 MS Access DB,而我在我的盒子上使用的是 Access 2007。帮助?