I am currently creating dynamic SSIS packages that import/export and access data between a SQL Server and several Access DB files. (Jet files if you want to get technical.)
Anyways, everything is successful during testing, as long as my SSIS packages have hard-coded connection strings to the Access file. This is great and works fine. I am pleased with this.
The problem now begins when I change my VB.NET application to use dynamic connection strings to the Access DB file (the destination file, where the data will be placed). I have the Access DB file stored in my application as an "embedded resource".
Here is the code I use to create my Access destination file:
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
This works fine and it does produce the correct results, an Access DB file wherever I provide a path to. This works well when my SSIS packages have hard-coded connection strings.
once I change the connection strings to be dynamic, and re-run the same exact test, I get this error:
"Record(s) cannot be read; no read permission on 'MSysAccessObjects'"
My connection string regular expression in my SSIS package looks like this:
--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=;"
When I navigate to this file on my local hard drive, and attempt to open it, it prompts me that it is in an unrecoverable state and to repair it, which it never successfully does.
- Am I overlooking something regarding my file creation? (IO?)
- Am I overlooking something regarding Embedded Resources? (they seem pretty straight forward to me,but maybe I'm overlooking something obvious?)
- Is the state of my file corrupt? I can open it in VS.NET IDE and locally, with MS Access.
- Is it worthwhile to recreate this Access file? Ive read that you can copy the schema to a new file to avoid repairs? This sounds SOOOOO risky!!
Originally I thought this was a permission error, regarding the user role of the Access DB file and SSIS trying to use it. But I don't think that is it. The user is set to Admin and should (in theory) work.
I think to hack/fix this I will currently try to NOT use embedded resources. I will use FileIO calls to move the file explicitly to the folder I want and populate it from there. Does anyone know why the embedded resource db file would not work, but the same file does work when not produced from an embedded resource? Is there something that is not completing when I create my file from the resource?
Any feedback or suggestions are greatly appreciated. Any questions are welcomed too. Thank you.
**** Update/07/18/2009:**
I modified my [CreateDestinationFile] routine to perform a direct File/IO copy, instead of using an embedded resource.
Here is the code for that:
Dim sPath As String = My.Application.Info.DirectoryPath + "\databasenamehere.mdb"
FileIO.FileSystem.CopyFile(sPath, path + "databasenamehere.mdb", True)
The file is correctly copied from the project, but I now receive this error:
"An OLE DB error has occurred. Error code: 0x80040E09. An OLE DB record is available. Source: "Microsoft JET Database Engine" Hresult: 0x80040E09 Description: "Record(s) cannot be read; no read permission on 'TABLE_XXXXX'."
This leads me to believe that SSIS does not have proper permissions to use my local MS Access DB as a destination file.
This is strange to me because the same file works if I hard-code the connection string to it in my SSIS package. What is going on here?
As you can see in my connection string expressions, I have [Admin] as the user. So this should work, right? Also, another possible culprit of this problem is the fact that this is a legacy MS Access DB created in Access 2003, and I am using Access 2007 on my box. Help?