Migrate MS Access back-end to SQL Server - sql-server

I am incredibly frustrated!
I have been trying for months to migrate a MS Access database to SQL Server and nothing has worked. I need to be able to edit data on an Access front-end and the SQL Server back-end.
I've been able to copy a table, but edits on one end are not applied on the other. I'm severely limited in what applications I can download -- it takes at least a week for our IT department to install a new app. I've tried using SSMS 18 (just had it installed today) to create a linked service.
I use "Microsoft Office 12.0 Access ..." (16.0 is not available) as the Provider and leave Product Name and Provider String blank -- I get this error for either a .mdb or a .accdb file.
TITLE: Microsoft SQL Server Management Studio
The linked server has been created but failed a connection test. Do
you want to keep the linked server?
ADDITIONAL INFORMATION: An exception occurred while executing a Transact-SQL statement or batch.
(Microsoft.SqlServer.ConnectionInfo)
Cannot create an instance of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "2022_08_24".
(Microsoft SQL Server, Error: 7302) For help, click:
https://learn.microsoft.com/sql/relational-databases/errors-events/mssqlserver-7302-database-engine-error
The generated script is
USE [master]
GO
EXEC master.dbo.sp_addlinkedserver #server = N'2022_08_24', #srvproduct=N'', #provider=N'Microsoft.ACE.OLEDB.12.0', #datasrc=N'C:\Users\liptonj1\OneDrive - Southern California Edison\Documents\Word Test_be.accdb'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'collation compatible', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'data access', #optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'dist', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'pub', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'rpc', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'rpc out', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'sub', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'connect timeout', #optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'collation name', #optvalue=null
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'lazy schema validation', #optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'query timeout', #optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'use remote collation', #optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption #server=N'2022_08_24', #optname=N'remote proc transaction promotion', #optvalue=N'true'
GO
USE [master]
GO
EXEC master.dbo.sp_addlinkedsrvlogin #rmtsrvname = N'2022_08_24', #locallogin = NULL , #useself = N'False'
GO

The right process is the one implemented by SSMA for Access: https://www.microsoft.com/en-us/download/details.aspx?id=54255
After creating matching tables and migrating the data the last step is to replace the Access tables with ODBC linked tables to the SQL Server so your Access-based forms and reports work directly with the SQL Server data.
Having a linked server from SQL Server to Access is not needed.

Ok, there is ALSO a 3rd option.
Access 2010 was the LAST version of Access to have a built in SQL server migration tool.
So here we are in 2022 12 years later!!!
but, Access 2010, and in fact Access 2007? It has a BUILT IN migration tool!!!
This is on the 2007 menu:
So, AFTER 2010, you ARE strong suggested to use the SSMAA - a seperate download and install.
However, Access 2003, 2007, and 2010? They have a BUILT-IN migration tool to sql server.
I don't have a 15 year old version of Access kicking around anymore, but you may very well want to try and use that tool. Just make sure you DO NOT use or pick the "ADP" option.

This is more a comment than an answer but is too long for a comment.
Try the following steps:
Using SSMS create a database
With that database (right mouse click) use task/import data and connect to your Access database using the Access connection type
Select the table(s) to copy (and copy them)
In your Access front end, connect to the SQL Server database using an ODBC connection and link the source tables
You can then read/write to them directly

While often not the case, we assume that you have a split access database.
That means that you have so called front end (accdb, or mdb). (FE)
And then you have linked tables to a back end (accDB, or mdb). (BE)
And office 12? Ok, that is version 2007 - 15 years old, but should work just fine.
(what other software are you using that is 15 years old? Or are you for some strange reason singling out Access for such a old version???).
Regardless?
So, the basic idea here?
You migrate the tables from the BE to sql server.
You then delete your FE links that point to the Access back end, and now are to create links in your FE that point/link to SQL server (where you presumably) migrated the Access data tables.
Hence:
I've been able to copy a table, but edits on one end are not applied on the other.
Sounds like your FE is still pointing to the older database. I mean EVEN without SQL server, it was often VERY easy to have your FE point to the WRONG database BE. You start editing, and you don't see changes in the database!!!!
So, once you move data to SQL server, then in your FE, you are to delete links
(you are NOT deleting tables here, but ONLY the linked tables in the FE, right, since we DO NOT have tables in the FE, do we?).
why do I export/import the tables, just to delete them?
You are NOT deleting tables!!!! - you are to delete your "linked" tables, or the so called links in your Access FE. You are now not using the BE anymore, and editing of data in your access FE will be directly working against and editing the table(s) that reside on SQL server. There is no concpet of suffeling data between tables - you are using linked tables. The data does NOT exist in the FE, and it never did with linked tables. So, you are being told to delete the linked tables - not the physical tables that were in your BE.
I mean assuming your Access applcation was split, then you don't have the tables in your FE to delete anymore do you? So, no, we not deleting ANY tables here, you are to delete the LINKED tables in your FE that previous pointed to your accDB BE.
You will THEN create NEW table links that now point to the tables you migrated to SQL server.
So, if you not using SSMAA?
Then you use the sql studio tools to create a database in SQL server.
Once you created a database, you are THEN to move the Access table(s) into that database. So, it comes down to what tools you plan to use for this task.
As a result, there is no "shuffle" of data between tables. You have a linked table in your FE. You are directly editing data in that linked table. But, now the linked table is not a access one, but one that resides on SQL server.
Ok, so above quite much outlines the moving parts and how this works.
So, lets take ONE simple table in a Access database. And lets import that table to SQL server. (but as noted, since this is one table, then we can use a simple import. But, AGAIN, if you have a boatload of tables in that Access database, then a dedicated migration tool is MANY times a better choice then a simple import of a table).
So, the first step would be to create a database. This is much similar to Access. You create a new database, and THEN you are to migrate(or import) the Access tables (and data) into that SQL server database.
Once done, then step 2 is to create a linked table to that table sitting in/on sql server.
So, we fire up SSMS, and create a new table.
So, we right click on databases, and choose new database.
And then just type in a name for our database.
And now hit ok.
Now, we right click on this database, and choose import data.
eg:
Now, in this example, we will import just one table.
So, in the import options, we see/get somthing like this:
Note the number of choices. Well, if this is a mdb file, then from above choose the "JET" database engine.
But, if this is a accDB file? (access 2007 and later), then choose the Access data engine as I have.
(and you might have to change the file drop down from *.mdb to all files.
So, that selects the file.
Now next page, you have to select the sql server "driver".
You have TOO many choices here - and it can be VERY confusing.
So, by FAR the best choice here is to ALWAYS choose a SQL server NATIVE driver. (you don't have to - but it will be more pain and suffering if you don't).
So this one:
thus this:
And again, don't know if you using SQL server logons, or windows security here.
Ok, so now we get:
I'm ONLY selecting one table (because this is a CRAP AND BAD way to do a data migration by using a simple import - but we have to start somewhere!!!).
So, at this point, we should be able to expland our database, and see the ONE table.
this:
Ok, so now right click on this table and choose design.
The table designer in SSMS is VERY much like access, so it should be easy to do the next steps:
REMEMBER WHAT I stated above. The import option above we used is a POOR way to import data to SQL server WHEN the goal is to use our Access FE to link to this table.
The REASON WHY is becuase the import option is kind of like a dirty and quick import choice for Excel and flat files and is quick and dirty.
But, it does NOT set our primary key, and all the other settings we would typical have in the Access table (such as PK column, and autonumber).
So, now in design mode, we WILL set the PK column.
So click on the PK column (should be in most cases "ID" - the default for Access).
Then up in the SSMS menu, click on the primary key button.
this:
Ok, that gets the PK (primary key setting).
Now we ALSO need to set this PK as "auto number" (like it was in Access).
So this setting:
So, again, "ID" is selected, and in the property sheet, set the column to "is identify" "yes", and it will put in the 1 and 1 for Increment and seed.
You can now close this table.
So, as noted, for 1 or 2-3 tables, you have to do the above for each table.
As I stated, if you have 40 and ALSO related data and tables, then we want to use a automated tool (like the SQL migration assistant for Access - SSMAA).
But, for this ONE table test, then the above is just fine.
Ok, so now we go to our Access FE, and we can delete this one table that was linked to the back end. (again, we not deleting a table, but ONLY the old existing LINKED table).
Now we create a new linked table to the SQL server table.
In access, then this:
So that option allows us to import or link (we are going to link here).
and we get to this:
ALWAYS NO MATTER what, choose (leave the default to FILE) as per above, do NOT use Machine Data source).
Next we choose the ODBC sql server driver.
WHEN POSSBILE ALWAYS choose a native driver. However, this choice depends if you going to distribute your FE to many users. (the native 11, 12 and up to 18 drivers are NOT installed by default). If you don't see any native drivers, then choose "SQL Server", but the native drivers are a better choice (but the down side is these drivers will have to be installed on all computers. The "SQL Server" one can be a good choice, since it ALWAYS will exist on every computer).
In fact, for this lets go with SQL Server one.
So, this one:
So then this (choose a name) for the conneciton.
next, then finish, and we get this:
The drop down SHOULD show a list of SQL servers you have.
then choose your logon.
I don't know if you using windows authentication, or SQL server passwords.
Then:
SUPER SUPER IMPORTANT STEP!!!!!!!
MAKE SURE you choose your database with this drop down - don't skip this!!!!
Check the box Change the default database to box, and then choose your database we created.
This we can just hit next - nothing to change.
then this - you can (should) try the test data Source button.
Now we are all the way back to the near starting panel, and you can hit ok
And now we get/can select the table to link to:
find your table - select it, and ALSO check that save password button.
At this point, you should see a linked table in Access. If we open it, we get this:

Related

multiple logins with sql server linked server

I have a database server out there - lets say the url is "the.database". It has several databases on it - db_a, db_b, db_c - that all require different users and passwords.
I can happily link to one of them like this:
exec master.dbo.sp_addlinkedserver #server='the.database' #srvproduct='SQL Server'
exec master.dbo.sp_addlinkedsrvlogin #rmtrvname='the.database' #useself='false'
#rmtuser='user_a' #rmtpassword='password_a'
select top 10 * from [the.database].db_a.dbo.some_table;
And that works great. For one of them.
However - what I want to do is connect to the server simultaneously with three different logins, and I can't figure out how to do it... in fact - what I'd really like is three different linked servers - db_a, db_b, db_c - which all actually point to the.database.... but if you use "sql server" as the product, it seems like the internal server name has to correspond to the url of the actual server? In the perfect world, I'd love to end up with being able to do:
select top 10 * from [db_a].some_table
where db_a actually means database dba schema dbo on server the.database.
So basically - is there a way to create a linked server with an internal name that doesn't match the external url? Or is there another way of solving this problem?

SQL Server Trigger on a Linked Server for reporting services

I have and SQL server with a report table that is linked to an SQL database on a separate server. The linked server is maintained by a 3rd party vendor so I'd rather not add triggers... I was hoping to run a report based on a value being inserted on a linked table. Tried the following:
CREATE TRIGGER [dbo].[RunReport] ON [linkedServer].[database].[dbo].
[CustomerComments]
FOR INSERT
AS
exec [ReportServer].dbo.AddEvent #EventType='TimedSubscription',
#EventData='xxxxx'
I get the error "contains more than the maximum number of prefixes. The maximum is 2." Anyway to trigger my report without altering the linked database. I also created a view of the linked table that didn't work either.
Thanks,
Leaving aside the idea, you can create the trigger on linked server this way:
exec [linkedServer].[database].sys.sp_executesql N'CREATE TRIGGER [dbo].[RunReport] ON [dbo].
[CustomerComments]
FOR INSERT
AS
exec [ReportServer].dbo.AddEvent #EventType='TimedSubscription',
#EventData='xxxxx'

Query database running on another physical SQL Server

Historically we have a product which installed two databases on the same server. There is an custom application which assumes that both databases are on the same server.
In a new version they have split the databases onto two separate servers and obviously now the custom application is giving the error:
Database 'DB_2' does not exist. Make sure that the
name is entered correctly.
Is there anything I can do in the SQL Server setup so that the application is still able to query the DB_2 database without modifying the custom application?
The query being used is structured as follows:
Use DB_2
SELECT * FROM MyUser.MyTable
You can create a linked Server, then Create a Database DB_2 add a Synonym for different objects. something like below.
use master
GO;
EXEC master.dbo.sp_addlinkedserver #server = N'RemoteServer', #srvproduct=N'SQL Server'
GO
CREATE DATABASE [DB_2];
GO
USE [DB_2]
GO
CREATE SYNONYM [MyUser].[MyTable] FOR [RemoteServer].[db].[MyUser].[MyTable]
GO
You can use Linked Servers feature. In SSMS go to Server Object/Linked Servers folder in Object Explorer. And link second server. So you can query another DB using this SELECT * FROM [Linked_Server_Name].[Database_Name].[Schema_Name].[Table_Name]

Linked Server from Sharepoint 2010 to SQL Server 2012

I'm trying to create a linked server in MSSQL to SharePoint in order to be able to write some storedprocs so that I can access them in Reporting Services.
I have created the link using the following...
EXEC master.dbo.sp_addlinkedserver #server = N'LINKTOSHAREPOINT', #srvproduct=N'ACE 12.0',
#provider=N'Microsoft.ACE.OLEDB.12.0', #datasrc=N'http://xxxx/CustomerService/Lists/',
#provstr=N'WSS;IMEX=1;RetrieveIds=Yes;LIST={3B85B1FA-C2C2-4D30-9DD4-0C42C6F85545}'
EXEC master.dbo.sp_addlinkedsrvlogin #rmtsrvname=N'LINKTOSHAREPOINT',#useself=N'True',#locallogin=N'sa',#rmtuser=NULL,#rmtpassword=NULL
I'm as confident as I can be that the List Guid and the server names are all correct. the Linked Server appears to connect but returns only "node" level info...
Catalogs --> Default --> Tables
But everything is empty.
I'm fairly sure it feels like a security issue, but I'm again confident that the windows login I use has access to most things.
Has anyone got any ideas or has even had this sort of thing working?

SQL Server cross database alias

I'm trying to understand how I can use an alias to reference another database in the same instance, without having to use a hardcoded name.
The scenario is as below:
I have a data db with stores data, an audit db which keeps all changes made. for various reason, i want to keep the audit data in a separate database, not least because it can get quite large and for reporting purposes.
In the data db, I don't want to reference this by a hardcoded name but an alias so that in different environments, I don't have to change the name and various sp's to reference the new name.
for example:
mydevdata
mydevaudit
If a sp exists in mydevdata such as which calls the mydevaudit, I don't want to change the sp when I go to test where the db's may be called mytestdata and mytestaudit. Again, for various reasons, the database names can change, more to do with spaces an instances etc.
So if I had procedure in mydevdata:
proc A
begin
insert into mydevaudit.table.abc(somecol)
select 1
end
when I go to test, I don't want to be change the procedure to reference another name, (assume for sake of argument that happened)
Instead I am looking to do something like:
proc A
begin
insert into AUDITEBALIAS.table.abc(somecol)
select 1
end
I am interested in finding out how I could do something like that, and the pro's and cons.
Also, dymnamic SQL is not an option.
thanks in advance for you help.
You may be able to use synonyms
CREATE SYNONYM WholeTableAliasWithDBetc FOR TheDB.dbo.TheTable
This means all object references in the local DB are local to that DB, except for synonyms that hide the other database from you.
You can also use stored procedures in the audit DB. There is a 3rd form of EXEC that is little used where you can parametrise the stored proc name
DECLARE #module_name_var varchar(100)
SET #module_name_var = 'mydevaudit.dbo.AuditProc'
-- SET #module_name_var = 'whatever.dbo.AuditProc'
EXEC #module_name_var #p1, #p2, ...
Obviously you can change module_name_var to use whatever DB you like
I've just posted this to How to create Sql Synonym or "Alias" for Database Name? which is a workaround for the same situation:
There is a way to simulate this using a linked server. This assumes you have two SQL servers with the same set of databases one for development/test and one live.
Open SQL Server Management Studio on your development/test server
Right click Server Objects > Linked Servers
Select New Linked Server...
Select the General page
Specify alias name in Linked server field - this would normally be the name of your live server
Select SQL Native Client as the provider
Enter sql_server for Product Name
In Data Source specify the name of the development server
Add Security and Server Options to taste
Click OK
The above is for SQL Server 2005 but should be similar for 2008
Once you've done that you can write SQL like this:
SELECT * FROM liveservername.databasename.dbo.tablename
Now when your scripts are run on the development server with the linked server back to itself they will work correctly pulling data from the development server and when the exact same scripts are run on the live server they will work normally.

Resources