I wrote a function to relink SQL Server tables in an Access app. That works great, except if I want to change the .connect property to a server where I have no access. In that case, the tableDef.Refresh generates an error.
Is there a trick I could use to relink from DEV to PROD before deployment when I have no access to PROD ?
I thought about replacing all linked tables pointing to SQL Server by Passthru queries (select * from tableX). Any other idea ?
Access will not RefreshLink a link whose Connect property points to a data source which is unavailable. That limitation applies not just to server database data sources, but any type of data source.
Create a function you call from an AutoExec macro which checks whether the application is running the first time in the PROD context. And if it is, set the linked tables Connect properties and call RefreshLink.
Related
We have a Server A and a Server B.
In Server A we have our ERPs made in Access and VBA.
In Server B we have an instance of SQL Server that needs to stay in that server.
Some Access databases need to link to some tables from that SQL Server instance and I don't want the password to be stored in the MSysObjects table, so I cannot manually link the tables checking the save the connection option.
I saved the connection string in a table with password obfuscation. With that connection string I re-link the tables on startup.
The instance is accessed through it's IP, not the name of the instance. If I use the name of the instance it doesn't work.
It works for me but not for other users except one.
The SQL Server instance has been properly configured to allow remote connections, the ports have been opened and rules added to firewall. If it wasn't properly configured it wouldn't work for me and the other user, so I'm pretty confident in that. The same with the connection string and the methods to stablish the connection in Access.
What I've tried:
Installing the SQL Native Client 11.0.
Installing a full SQL Server Express.
Configured the SQL Browser service to star automatically instead of being disabled.
Step 1 did not work for any user. Step 2 did work for one user but not for the rest. Step 3 did not had any effect. For me I had it installed in my machine since forever, so it doesn't apply.
If I try to do the same with a SQL Server instance in our LAN it works for every user, but not when the instance is in a remote server.
Note I have limited knowledge. Maybe I say something that does not make sense.
Ok, a few things:
Installing the SQL Native Client 11.0.
Ok, then you have to re-link the tables - choose the new driver. A refresh of the linked tables is NOT sufficent. And this ALSO means that each work station ALSO now must have native 11 instlled. And if you say decide to link using native 17 (a much newer odbc driver), then AGAIN YOU must install this native driver on each work station. While you can install multiple sql drivers on each workstation, the driver you used to link the tables MUST ALSO be installed and exist on each work station.
Installing a full SQL Server Express.
Why? What would installing a copy of sql server have to do with OTHER sql servers on other machines that you are attempting to connect to? You think installing sql server on a machine effects the sql server running say on amazon.com? So, this move makes no sense at all.
You are attempting to connect to some instance of sql server running on some other computer. Makes no sense nor will it help to install some copy of sql server that you not using, not connecting to, and that has zero to do with this issue.
Configured the SQL Browser service to star automatically instead of being disabled.
Where? The browser service is set to run and startup on the server and SAME machine where sql server is installed and running. So, yes, without question, those two sql servers A, and B most certainly MUST have the sql browser service running. That service is what allows the client computers to connect to that running instance of sql server. In the past, older (previous) versions of sql server would allow a default connection, but now in near all cases, you MUST ensure that the sql browser service is running on that computer that also has the database you are attempting to connect to.
it's worth to note that the instance is accessed through it's IP, not the name of the instance.
No, you likly have this incorrect. There are two part.
The server name - and then the "instance" of sql server running.
While you can swap out (not use) the server name, you STILL WILL NEED to specify the sql server instance.
So, you can use this format:
myservername\SQLEXPRESS
Or, you can replace the server with a IP address, but you STILL NEED the sql server instance. (by default, it is SQLEXPRESS - but you have to check what the instance of sql server database is).
192.168.1.30\SQLEXPRESS
So while you can use IP or server name - it is often more reliable to use the IP address, but that does NOT get you off the hook from having to specify the sql instance you connect to. Again, previous editions of sql server often allowed a "default" instance, and you did not in general have to specify the "instance", but now you do. And to be double clear, when using such a instance, that sql server needs to be running the sql browser service. (in fact, the browser service is what translates the incoming request to the given and correct instance of sql server).
I DON'T want the password to be stored in the MSysObjects table,
You don't have to, and in fact should NOT include the uid/password in your connection string. And in fact ZERO reason exists to do so.
What you do is execute a one time logon, and THEN link the tables without UID/password. This is not only a great idea, but it also means that your uid/password is not included in the connection strings, but also means users can't get at, or even by accident see/get the uid/password.
It also means that say someone where to launch a copy of access, and import the linked tables from this applcation. When they attempt to use the linked tables, they will NOT work.
So, then how do linked tables work without a password? (and this ALSO by the way saves you from having to re-link tables on startup!!!).
The way this works, is you in code execute a one time logon to the server on startup. That means you can either:
Prompt the user for their sql UID/password.
or
Have in code, the uid/password. (or perhaps in a text file y ou read on startup. You can thus hide, or encrypt or whatever for that uid/passwords.
Then in your startup code, you execute a one time logon. Once you done this, then all linked tables will now work - and work without having uid/password.
since you have two servers then you need to execute two logons, one for server A, and one for server B. But, once again, as long as the linked tables exist, then they will work.
Now, there are "longer" articles on how to use this logon idea, and then not have to include, or re-link your tables for the SQL uid/password.
The basic code to execute a logon is like this:
Function TestLogin(strCon As String) As Boolean
On Error GoTo TestError
Dim dbs As DAO.Database
Dim qdf As DAO.QueryDef
Set dbs = CurrentDb()
Set qdf = dbs.CreateQueryDef("")
qdf.connect = strCon
qdf.ReturnsRecords = False
'Any VALID SQL statement that runs on server will work below.
' this does assume user has enough rights to query built in
' system tables
qdf.sql = "SELECT 1 "
qdf.Execute
TestLogin = True
Exit Function
TestError:
TestLogin = False
Exit Function
End Function
Keep in mind, that ONCE you acheived a legal logon, then EVEN addtional logon attempts will return true.
Not usually a big deal, but this means you supply a valid connection to above, and if it logs on and works - then now all your linked tables (without uid/password) will work.
I note the above issue that ONCE you done the logon, then all 2nd or more times running the above will work (even if bad or incorrect!!! - DO NOT forget this tip!!!). (this can confuse the daylights out of a developer, since they execute logon, (or open a table). Then they test above routine with a BAD uid/passwords, and it works!!!
So, you have to EXIT access to clear out the password cache - no other way.
So, keep the above tips in mind.
First, I know the syntax of calling a procedure on a linked server and I am familiar with the RPC and RPC Out server options at a basic level. What I am being told is that a procedure I created cannot be seen by navigating the tree of the linked server.
One caveat is I do not have access to the server where this person is working which is linked to the server on which I have the procedure - I hope that is clearly stated. At this time he is getting the "not configured for RPC" error on execution and I have told him to check the linked servers options. So ultimately, do the RPC linked server options control whether the procedure can be seen?
I've been told that other views can be seen. Also, I am confident it is not a permissions issue. The user involved has access to a role which has access to my procedure.
Thank you for your time.
In the Linked Server, Properties, Server Options there are two RPC settings.
Set them both to true.
What do you mean by do not have access?
You cannot Connect to that server?
That is how I tested this.
Connect to any server, create a Linked Server back to yours, and test.
This is true:
In the Linked Server, Properties, Server Options there are two RPC settings.
Set them both to true.
You also need to verify that the credentials used inside the linked server connection has rights on the linked server.
Grant connect, and access to the database that has the stored procedures that you need access too. You will then grant execute to the procedures you need to run.
If you have connection issues, open SSMS using the credentials you have used to create the linked server on the database server you are trying to link from and verify connectivity and database access. If you can see the objects your after, then the linkedserver connection is the problem. Try creating a new one and see if you have better luck that way.
My SQL Server database table has a column that needs to be Updated with data from an MS Access file. How do I query the MS Access data to perform such an update?
Import Wizard seems to only handle Inserting of new data and not UPDATE existing data? Or am I misunderstanding how to use the wizard?
Sounds like you want to run that operation from the SQL Server side ... "pull" the Access data into SQL Server. If so, you can set up the Access file as a linked server within SQL Server. I've not done that, but have read cases where other people have. I copied these steps from How can I link a SQL Server database to MS Access using link tables in MS Access? at SQLServerPedia.
1) Open EM.
2) Goto the Server to which you want to add it as linked server.
3) Then goto security > Linked Servers section from console tree.
4) Right click on the Client area. Then New Linked Server.
5) Give a name and Specify Microsoft Jet 4.0 as Provider string.
6) Provide the location of the MDB file.
7) Click OK.
Alternatively, you could run the operation from the Access side, and push the data to SQL Server. If that could work for you, use Olivier's instructions to set up the ODBC-linked SQL Server table. Or you do it without creating a DSN: Using DSN-Less Connections.
Either way you link the table, the UPDATE statement you run from within Access might then be as simple as:
UPDATE
linked_table AS dest
INNER JOIN local_table AS src
ON dest.pkey_field = src.pkey_field
SET dest.access_data = src.access_data
WHERE
dest.access_data <> src.access_data
OR dest.access_data Is Null;
First set up a ODBC DSN in Windows. Open Control Panel > Administrative Tools > Data Sources (ODBC). Note that on 64 bit Windows, this might open the 64-bit-administrator. However, if you have a 32-bit Access, you need the 32-bit-administrator (%windir%\SysWOW64\odbcad32.exe).
Then you can link the SQL-Server tables to your access db. In the Link Tables dialog, choose "ODBC Databases()" as file type.
You can then query the linked SQL Server tables as if they were access tables.
See Configure Microsoft Access Linked Tables with a SQL Server Database
Can I use OPENDATASOURCE (or another mechanism) from a Stored Procedure to connect to the same database as a different user? If so, how?
The database is meant to be deployed to several customers, and replicated by them as many times as they want to, etc. For this reason, I CANNOT HARDCODE the database server's name or the database's name.
(I tried using OPENDATASOURCE, but it only accepts hardcoded connection strings.)
Might EXECUTE AS work in your situation? http://msdn.microsoft.com/en-us/library/ms181362.aspx
You can set up a Linked Server to connect to the remote server using the login's current security context (or other options as it applies to your situation).
From your stored procedure, you could access it with something like SELECT * FROM mylinkedservername.mylinkedserverdatabase.dbo.mytable
But you say you want to connect to the same database but using a different login? You're looking for impersonation. Perhaps you can do this making a Linked Server that references itself, I haven't tried it. Search Microsoft Help documentation for how to set it up normally and test if it does what you're looking to do.
I'm creating a setup using Inno-setup.
During the setup process, a SQL Server database has to be created. I want to give the user the ability to select an existing SQL Server instance (if one exists), where the database has to be created.
So, what I want to do in the setup, is to query the network (and the local machine) for SQL Server instances.Furthermore, when the user has selected an instance, I want to verify if there exists a database on that instance which has a specific name.
Anybody who knows how I can do this ? Or maybe someone could give me some pointers in the good direction?
Inno Setup supports the call of external DLL functions, so you should write a suitable helper DLL. Managed .net DLLs can only be used via a COM interface, otherwise you need an unmanaged DLL.
Valid calling conventions are: 'stdcall' (the default), 'cdecl', 'pascal' and 'register'.
Try the following native .Net library call:
using System.Data.Sql;
var instance = SqlDataSourceEnumerator.Instance;
DataTable dataTable = instance.GetDataSources();
The resultant datatable contains the following columns:
ServerName
Name of the server.
InstanceName
Name of the server instance. Blank if the server is running as the default instance.
IsClustered
Indicates whether the server is part of a cluster.
Version
Version of the server (8.00.x for SQL Server 2000, and 9.00.x for SQL Server 2005).