SQL SERVER Triggers interfere in MS-Access [duplicate] - sql-server

My application is a front end MS Access application linked to a SQL Server database.
I have a form in MS Access for the Orders table and a sub form for Orderslines table
In the OrdersLines table, there is a trigger which calculates the total sum (Quantity x unit price) and more.
The "funny" thing, in MS Access, when I create a new order, I cannot modify the Orders table, because the database and access have not the same data.
So when I run me.requery in MS Access after the process of new order creation, the me.requery sends me to a new record.
This is not happening when I modify this command.
I have tried many things but I can't get it working to keep the current record with a new command.
Any idea will be welcome
Nico

The easiest way to solve this problem is to add a single TimeStamp field to each of your SQL Server tables.
Microsoft Access can track the changes to records in SQL by the TimeStamp field, and it will automatically requery the data from SQL Server and eliminate the "The Data has been modified by another User" message.
The field you add can have any name you wish (I use the name tsJET as this field specifically helps the JET/ACE engine track record changes in this case) and the type for the field is TimeStamp. You don't have to include this field in any queries or forms, it simply needs to exist in the table.
Be sure to refresh the table links after adding this field to your SQL Server tables so that Access can "see" the structural changes to the tables.
NOTE: You cannot modify the data in the TimeStamp field. SQL Server handles that automatically.

Related

SQL Server triggers + MS Access forms

My application is a front end MS Access application linked to a SQL Server database.
I have a form in MS Access for the Orders table and a sub form for Orderslines table
In the OrdersLines table, there is a trigger which calculates the total sum (Quantity x unit price) and more.
The "funny" thing, in MS Access, when I create a new order, I cannot modify the Orders table, because the database and access have not the same data.
So when I run me.requery in MS Access after the process of new order creation, the me.requery sends me to a new record.
This is not happening when I modify this command.
I have tried many things but I can't get it working to keep the current record with a new command.
Any idea will be welcome
Nico
The easiest way to solve this problem is to add a single TimeStamp field to each of your SQL Server tables.
Microsoft Access can track the changes to records in SQL by the TimeStamp field, and it will automatically requery the data from SQL Server and eliminate the "The Data has been modified by another User" message.
The field you add can have any name you wish (I use the name tsJET as this field specifically helps the JET/ACE engine track record changes in this case) and the type for the field is TimeStamp. You don't have to include this field in any queries or forms, it simply needs to exist in the table.
Be sure to refresh the table links after adding this field to your SQL Server tables so that Access can "see" the structural changes to the tables.
NOTE: You cannot modify the data in the TimeStamp field. SQL Server handles that automatically.

SQL Server table daily sync of records from table A to table B

I want to create a daily process where I reload all rows from table A into table B. Over time table A rows will change due to changes in source system and also because of aging/deletion of records in the origin table. Table A gets truncated/reloaded daily in step 1. Table B is the master table that just gets new/updated rows.
From a historical point of view, I want to keep track of ALL the rows in table B and be able to do a point in time comparison for analytics purposes.
So I need to do two things, Daily insert rows from table A to table B if they don't exist and then also create a new record in Table B if the record already exists but ANY of the columns have changed. At one point I attempted to use temporal tables but I had too many false/positives on 'real' changes, basically certain columns were throwing off things because a date/time column was updated(only real change in row).
I'm using a Azure SQL Server Managed Instance database (Microsoft SQL Azure (RTM) - 12.0.2000.8).
At my disposal I have SSMS, SQL Server and also Azure Data Factory.
Any suggestions on the best way to do this or tools to help with this?
There are 2 concepts out of which you can implement any one.
Temporal table
Capture Data Change (CDC)
As CDC is the commonly used approach in which you can create an Azure data factory with a pipeline that loads delta data based on change data capture (CDC) information in the source Azure SQL Managed Instance database to an Azure blob storage.
To implement the CDC, you can you can follow this simple Microsoft tutorial Incrementally load data from Azure SQL Managed Instance to Azure Storage using change data capture (CDC)
Note: You also need to Create a storage account which is required but not given in above tutorial.

SQL Server migrate new data into old schema

I have converted MS Access tables and queries to SQL Server tables and views and linked them back to Access. While I was doing this migration, people were using the old Access frontend not linked to SQL Server. Now, the data that I have in SQL Server is the old data when I started the migration. I have created tables, indexes, queries etc in my SQL Server which uses the old data.
Now, I want to deploy the SQL database and link it to Access. Is there a way for me to delete my old data and migrate the new data to SQL Server database while preserving all the schema?
Edit 1:
If you did the migration using SSMA (Sql migration assistant for Access) then you can simply re-run that saved project.
The first time you run SSMA, it will create the data tables on sql server, and then transfer the data.
However, you can open that same SSMA project again, and re-run it, will give you the option to delete the data on SQL server, and send up the existing Access data again.
One of the “really” great features of SSMA is it lets you re-send the data. So you can slice and dice, and try the migration MANY MANY times.
Once you get the migration going the way you want, you migrate the data. You then work on getting your front end to work with sql server. During this time, no doubt users are still using the older system (non sql server).
For example, SSMA allows you to add a PK to each table (if it does not have one). I often found a “few” tables such as for driving combo boxes etc. does not (did not) have a PK for that table that say drives a combo box. So during the migration, you want to let SSMA create the PK for you. You can do this manually after the migration, but then you need to write down some “cheat” notes, since as you point out, you going to have to do the migration again later on.
So, if you make any “manual” changes to the data structures, then you want to “save” those changes in the event that you migrate again. The beauty of this, is WHEN you in the table design mode (sql server), you can right click, and choose “script” changes. So if you make say 10 or more changes to each table, you can save your changes into a sql script. So now you can migrate, and then run those scripts.
Now, after the migration, you get to work making this front end work with SQL server. During this time no doubt users are STILL working on the old system (access back end).
Once your new front end is working fine with sql server, then you pick a day for the new roll out. You after work, or during down time, re-run the SSMA project you saved. The result is now SQL server has the most up to date data. And then you are now able to roll out and deploy out the new front end that is linked to SQL server.
As noted, while SSMA can migrate Access queries, I VERY strong recommend you don’t do this. Just migrate the data, and link the front end tables to sql server. At this point, 99% of your Access appcation will work as before. You “may” have to change the VBA open recordset commands (to add dbOpenDynaset, and dbSeeChageesto that openRecordSet command (but that is a global search and replace – not much time at all).
So you likely have lots of code like this:
Set rst = CurrentDb.OpenRecordset(strSQL)
And you need to change above to:
Set rst = CurrentDb.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)
The above will thus allow 99% of your VBA reocrdset code to work as before without changes.
The only “common” got ya, is with a Access back end, the autonumber ID is generated INSTANT as a you dirty a form, or dirtry (add too) a record. This allows code to grab the auto number PK right away.
So such old code as:
Set rstRecords = CurrentDb.OpenRecordset("tblmain")
rstRecords.AddNew
' lots of some "code" here follows
lngPK = rst!ID
In above, note how my VBA code grabs the PK auto number.
In sql server, you cannot grab that PK until AFTER you force the record save. And DAO has a VERY nasty issue is that after you issue a update (during add only – I repeat during adding reocrds only!!!), then the record pointer jumps off the current record. This DOES NOT occur when you using DAO recordsets to update a existing record (again: only for new reocdors).
So, so above code now becomes:
Set rstRecords = CurrentDb.OpenRecordset("tblmain")
rstRecords.AddNew
' code can go here to add data, or set values to the reocord
rstRecords.Update
rstRecords.Bookmark = rstRecords.LastModified
lngNext = rstRecords!ID
rstRecords.Close
So, for code that grabs the autonumber PK right away, we have to do two things:
Force a record write (update)
And then after the update, re-positon the record pointer. (you ONLY need this re-postion when adding – not edits, but I often do this anyway). This re-position issue is perhaps my LARGEST pain of using DAO (ADO does not require this re-position).
So your code add/sets the fields etc. in that reocrdset do NOT have to be changes. So leave that code that does whatever the heck the code did before.
Now issue the update, AND THEN GRAB the autonumber PK.
So above should cover 99% of your VBA code you have to change. Even in a rather large project, the above issue will only occur in a few places. (I find that I can search for “.add” in the code base, and rather fast determine if code is grabbing the autonumber PK before the “.update” command is issued.
The same goes for forms. When a user starts typing, the form becomes “dirty”. With Access back end, the autonumber PK can be grabbed by code, but with sql server back end, you have to issue a record save in the form, and THEN grab the PK ID.
So, you add this one line:
If me.Dirty = True then me.Dirty = false
lngID = me!id
So you added the one line to force a record save (me.Dirty = false).
And again I tend to find even with say 150 forms, only 1 or 2 will do this “grabbing” of PK id before the forms record has been saved. So this “lack” of autonumber being able to grabbed for new records will occur for both forms, and VBA reocordset code. Few forms do grab the PK autonumber ID, but some do need this (say to add child records). However, existing forms + sub forms do NOT have this issue, since access ALWAYS issues a record save when the focus jumps from the main for to any sub form.
Anyway, once you get the new front end working (and of course one linked the front end using the same table names as before).
If I recall, SSMA tends to put “dbo” in front of the Access table link names – you don’t want that. The dbo schema on sql server side is the default, and again that should not pose any issues or problems.
So yes, SSMA allows you to re-run the migration, and it allows you to delete your data on SQL server during that re-migration. You not need to delete the old data, SSMA can do this for you.

MS Access linked table to SQL Server update record

I have a table in SQL Server 2012 (Table1) and I have created an MS Access 2016 database and then created a linked table in MS Access to Table1 in SQL Server 2012 using a System DSN.
This works fine, I can open the linked Table1 in MS Access 2016 see the columns and update the values. I have then created a Form in MS Access 2016, added the columns from Table1 to the Form and I can see the data fine.
The problem I have is that the option to Add New Record is greyed out and no matter what I try I cannot add a new record to Table1 using the Form.
If I create a standard (not a linked table) in MS Access 2016 and add the columns to the Form rather than the columns from the Linked Table1 the Add New Record icon is then available.
My question is... Is it possible to use a Form in MS Access 2016, have the data source as a Linked Table to a table in SQL Server 2012 and add new records to it? (And if so, how do I achieve this as I've been at this now for hours and hours and cannot figure it out).
Many thanks in advance.
You note that you can update values when you click on the linked table and view the rows.
Can you ADD rows when using that linked table? And if you cannot, then open up the table using SQL Management Studio and try adding rows that way?
If you don’t have correct (or any) settings in SQL server that sets up or increments the primary key, then you can’t add rows (automatic in this context).
So make sure the table has a primary key, make sure you can add rows using SSMS. If you make changes to fix this SQL table, then you have to re-link the table.
I suggest you create a primary key in the SQL table, and make it a identity column with a increment of 1.
It is certainly possible; this is a very common approach. It sounds like the login you used in the System DSN to connect to SQL Server does not have INSERT permissions on the table. Are you able to review the permissions to check that?
The auto-insertion/update doesn't work for link-database. You need to write a VBA code behind your interface.
Below solution can give you a basic and simple heads up:
Inserting into SQL Server using MS Access
Have a similar situation. Linked Sql Server table, Access Form front end. I am able to insert/update/delete via the form. However, I then created a checkbox to implement a filter on the data. When the box is not checked, I can still edit the data. However, as soon as I check the box to activate the filter, I can no longer insert/update/delete. When I uncheck the box, I can again edit the data. So in my case, the problem is due to the filter, which is implemented via a VBA query involving both an outer join and a union. The query replaces the form's control source when activated, and I believe it is simply too complex for Access to treat it as updatable.

Audit two different tables in SQL Server

I have a form with data. Any changes or insertion , those data should be updated in tow different tables like name, salary in one table and address, mail id in another table.
Like the example above i have several columns in both tables.
Now i want to audit the table. So i think i have to create a view for the two tables and set up a trigger for the view. Is it correct?.
And also i need to know only the affected columns. How to get the only affected columns?
Please suggest me a solution.
Thanks!!
There are lots of ways to let the system handle all that grunt work for you - depending on the SQL Server version you're using:
How to: Use SQL Server Change Tracking (as of SQL Server 2008)
Introduction to SQL Server change tracking
Understanding SQL Server Audit (as of SQL Server 2008 R2)
Articles for SQL Server Auditing (various versions)
If you really must handle all the work yourself, you need to get familiarized with triggers - read up on them in Data Points: Exploring SQL Server Triggers.
Inside your trigger code, you have two "pseudo-tables":
Inserted is the table holding the values being inserted (in an INSERT trigger) or the new values (in an UPDATE trigger)
Deleted is the table holding the values being deleted (in a DELETE trigger) or the old values (in an UPDATE trigger)
With those two pseudo-tables, you can get access to all data you might need.

Resources