Although you don't mention it in the question, I assume that the reason you're using an SSIS package rather than simply executing the stored proc from a SQL Agent job is that there are other steps in the process. My other assumption is that you schedule the SSIS package using a SQL Agent job.
The first error message implies that you are creating an OLEDB connection to your Access database but that the database could not be found. It's possible that this is a security problem, and that the Windows account under which the SSIS package is running does not have permissions to the file system location where the Access database is stored.
The second error message seems to back this up - when executing the SP, the linked server connection could not be opened.
To confirm this as the issue, you need to try running the SP in SSMS using the same account under which the SQL Agent service runs.
If this is the problem, you will need either to change the permissions of the SQL Agent service account to allow access to the target location, or copy the access db to a location that the account can access (possibly the local disk) before running the package.
EDIT - in response to additional details:
Now that permission and Networked Drive are mentioned, I think this
may be the problem. However, I am still confused as to why I am able
to manually execute the Stored Procedure from within SQL Server with
the Access DB on a Network Drive?
The Acess linked server is configured to use the security credentials of the account executing the query. When you execute the procedure from SQL Server Management Studio, you are doing so in the context of your Windows account, which must have permissions to the network share.
When the same query is executed by the SQL Agent service, it uses the security context of the service account under which the service is running, which does not have access to the share.
Finally, how can I apply this suggestion? Meaning where in SQL Server
do I configure this feature:
change the permissions of the SQL Agent service account to allow access to the target location
You can find out and change the account under which the SQL Agent service is running in the SQL configuration manager (should be found under Start > All Programs > Microsoft SQL Server 2008 > Configuration Tools. Find "SQL Server Agent" in the list of SQL Server Services and see the "Log On As" column). You may need to switch this to a domain account to get access to the share.
In the past I built a "fuzzy-search" in a .Net CLR function. This function gets called the same way a user-defined function gets called.
For example,
select id, name
from customers
where dbo.CompareStrings("newCustomerName", customers.name) > .8
would only return customers with a name that was 80% similar to the input name.
The % match is based on the number of changes needed to convert one value to another, not the number of characters that are different. We use it to compare addresses, and found this was more effective because of the numerous street abbreviations that are used.
Here's the code I used to compare strings. I did this so long ago that I can't remember how to deploy it, although a quick search will show you many articles on how to create SQL CLR functions
' Checks two strings against each other and returns a decimal between 0 (doesn't match at all) and 1 (100% match)
<Microsoft.SqlServer.Server.SqlFunction()> _
Public Shared Function CompareStrings(ByVal input1 As SqlChars, ByVal input2 As SqlChars) _
As <SqlFacet(Precision:=10, Scale:=4)> SqlDecimal
If IsNothing(input1) And IsNothing(input2) Then
Return New SqlDecimal(1.0)
ElseIf IsNothing(input1) Or IsNothing(input2) Then
Return New SqlDecimal(0.0)
End If
Dim s1 As String = New String(input1.Value)
Dim s2 As String = New String(input2.Value)
If s1.Length = 0 Or s2.Length = 0 Then
Return New SqlDecimal(1.0)
Else
Dim re As New Regex("[^A-Za-z0-9 ]", RegexOptions.IgnorePatternWhitespace Xor RegexOptions.Singleline)
s1 = re.Replace(s1, "( )\1*", "$1")
s2 = re.Replace(s2, "( )\1*", "$1")
s1 = UCase(re.Replace(s1, ""))
s2 = UCase(re.Replace(s2.ToString, ""))
Dim dif As Integer = GetStringSimilarity(s1, s2)
Dim max As Integer = s1.Length
If s2.Length > max Then max = s2.Length
Return New SqlDecimal(1.0 - (dif / max))
End If
End Function
' Compares two strings using the relationship in patterns of letters
Private Shared Function GetStringSimilarity(ByVal s1 As String, ByVal s2 As String) As Integer
Dim n As Integer = s1.Length
Dim m As Integer = s2.Length
Dim distance(n + 1, m + 1) As Integer
Dim cost As Integer = 0
If n = 0 Then Return m
If m = 0 Then Return n
For i As Integer = 0 To n
distance(i, 0) = i
Next
For j As Integer = 0 To m
distance(0, j) = j
Next
For i As Integer = 1 To n
For j As Integer = 1 To m
If Mid(s2, j, 1) = Mid(s1, i, 1) Then cost = 0 Else cost = 1
distance(i, j) = Min3(distance(i - 1, j) + 1, distance(i, j - 1) + 1, distance(i - 1, j - 1) + cost)
Next
Next
Return distance(n, m)
End Function
' Returns the min of 3 values
Private Shared Function Min3(ByVal x As Integer, ByVal y As Integer, ByVal z As Integer) As Integer
Dim min As Integer = x
If y < min Then min = y
If z < min Then min = z
Return min
End Function
Best Answer
The way we solved this was to use a template db to auto create views against the access linked tables. Each view was created as
Once these views had been created we could pull the column listing from sys.columns joined over to sys.views.
We could then insert this into the table we needed to work with.