I'm building a data warehouse for a client where one of the sources of data is a Dynamics AX database. For a given AX table I need to determine if a row has been inserted, modified or deleted, so it can be inserted, updated or deleted in the DW.
With regards to detecting a row having been modified, there appears to be two columns in most AX tables I could use for this purpose, ModifiedDateTime and RecVersion. I have two questions related to these columns:
1) Is the ModifiedDateTime column updated each time a row is updated? If so, is this value updated even if someone updates a row directly in the table, outside of an AX application (such as from a tool like SSMS)?
2) Same questions as above for RecVersion. Also, is the number globally unique across the entire database or just unique for the table?
Is there another alternative I'm not aware of to do what I want to do?
You want to use fields RecId and RecVersion, which are available in all business data tables of AX 2012. RecId is a unique value for each record of a table. RecVersion is 1 after a record has been created and is changed to some number other than 1 everytime the record is changed.
ModifiedDateTime is not a good choice, because it is not available on all tables.
Regarding you question if one of those fields is updated when someone modifies data directly in the AX business database: The answer is no and this is one of the reasons why you absolutely never should do such a thing. Honestly, I've seen several customers crash that did this against the explicit recommendations of their implementation partners. Dynamics AX offers several options to integrate data from other systems, use them and don't try to invent your own.
Regarding your question if RecVersion is globally unique: No. You can use a combination of TableId and RecId to uniquelly identify a record in the AX business database.
As I mentioned in my answer to your question How do I get the location for a row in dbo.CUSTTRANS?, AX comes with a data mart and also has some logic on how to update that based on changes in the business data. I'm not familiar with the details of those updates, but it might be worthwhile investigating them to see if you could reuse them for your purposes.
Some parts of AX 2012 use SQL Server Change Tracking under the hood (e.g. AIF).
Change tracking records deleted record as well, which neither ModifiedDateTime nor RecVersion fields can give you.
Related
I am new to Dataverse, moving from the SQL Server world, and just created my first Dataverse table (Standard table). Upon creation, the table has lots of what I assume are automatically-added columns? These include "Owner", "Status", "Version Number". I come from the SQL Server background where new tables come "empty", with no columns. I do not think I need these automatically-added columns (this is just going to be a small log table that holds datetime, action, etc. columns).
Would it break anything if these automatically-added columns were deleted? Also, if anyone could provide information about why these columns are included, that would help. I have researched these questions online, but found very little. Thank you in advance.
They are standard, out of the box attributes that you can't remove.
You can change the Ownership within the Table Type to "Organization" when creating the table to remove the Owner however the rest are created as part of every table.
There is some high level detail on the docs
https://learn.microsoft.com/en-us/powerapps/maker/data-platform/entity-overview
Dataverse (earlier called as Common Data service) is Dynamics CRM under the hood. It’s a SaaS model CRM online software comes with some basic fundamental components.
When you create a table (entity) it comes with columns (attributes), relationships, views, forms, dashboards, etc.
The UCI model driven app can be made quickly to include these components with all CRUD operations without any code by doing simple configuration and customization.
To support these barebone functionalities - the necessary attributes like name, currency, statecode, statuscode, createdby, createdon, modifiedby, modifiedon and security implication fields like owner, owning business unit, owning team and change tracking & concurrency fields like row version, etc will be created.
You can keep them aside as they are part of platform and do your customization as you need.
This is a more in depth follow up to a question I asked yesterday about storing historical data ( Storing data in a side table that may change in its main table ) and I'm trying to narrow down my question.
If you have a table that represents a data object at the application level and need that table for historical purposes is it considered bad practice to set it up to where the information can't be deleted. Basically I have a table representing safety requirements for a worker and I want to make it so that these requirements can never be deleted or changed. So if a change needs to made a new record is created.
Is this not a good idea? What are the best practice to deal with data like this? I have a table with historical safety training data and it points to the table with requirement data (as well as some other key tables) so I can't let the requirements be changed or the historical table will be pointing to the wrong information.
Is this not a good idea?
Your scenario sounds perfectly valid to me. If you have historical data that you need to keep there are various ways to meeting that requirement.
Option 1:
Store all historical data and current data in one table (make sure you store a creation date so you know what's old and what's new). When you need to retrieve the most recent record for someone, just base it on the most recent date that exists in the table.
Option 2:
Store all historical data in a separate table and keep current data in another. This might be beneficial if you're working with millions of records so you don't degrade performance of any applications built on top of it. Either at the time of creating a new record or through some nightly job you can move old data into the other table to keep your current table lightweight.
Here is one alternative, that is not necessarily "better" but is something to keep in mind...
You could have separate "active" and "historical" tables, then create a trigger so whenever a row in the active table is modified or deleted, the old row values are copied to the historical table, together with the timestamp.
This way, the application can work with the active table in a natural way, while the accurate history of changes is automatically generated in the historical table. And since this works at the DBMS level, you'll be more resistant to application bugs.
Of course, things can get much messier if you need to maintain a history of the whole graph of objects (i.e. several tables linked via FOREIGN KEYs). Probably the simplest option is to simply forgo referential integrity for historical tables and just keep it for active tables.
If that's not enough for your project's needs, you'll have to somehow represent a "snapshot" of the whole graph at the moment of change. One way to do it is to treat the connections as versioned objects too. Alternatively, you could just copy all the connections with each version of the endpoint object. Either case will complicate your logic significantly.
Suppose that I have a bank account table with columns customer_id, name, address, and balance. Balance is constantly changing because customer is depositing and withdrawing money. How can I chance customer's address without getting an DBConcurrencyException at the same time?
What is the general approach in this situation, it is not possible for two users to change the SAME cell in a table row but it is possible for them to change different cells in same row AND updating the row with new values without problem?
You should look at link http://blog.sqlauthority.com/2008/08/18/sql-server-detailed-explanation-of-transaction-lock-lock-type-avoid-locks/ which has detailed information.
I'm not sure if you are using LINQ, but if you are then you should take a look at how it handles concurrency. LINQ uses optimistic concurrency. So basically if a a user attempts to update a record, and the record has been updated in the interim, then a concurrency conflict occurs.
However, you can decide which properties in your LINQ table are used for concurrency checking-- in which case LINQ won't care if the value in that record was changed.
There are also ways to handle the exception- you could put a try block around the exception-- and write some code to handle different scenarios.
I have a Tariffs table for international dialing Codes
with StartDate and EndDate
I'm using ASP.net Application to import excel offers to this table , Each offer contain about 10000 row, so it is a large table (about 3 millions row)
what is the faster scenario in SQL Server 2008 to create a stored-procedure or trigger to change the previous endDate for same tariff same prefix same destination and new rate on insert a new row,
and how to undo saving offer of 10000 rows and get back the table and update records to the previous state
Thank you,
The information in your question seems a bit jumbled, partially because of the ideas within it but also unhelpful grammer/whitespace (sorry to be so blunt but these things are helpful) but I'll try my best to answer.
In general, assume that a trigger is slower than a stored proc. They also add a higher level of complexity than many other things, like procs, so always be sure you really need one before using one.
But, I don't understand why you'd need a trigger if you're only inserting into one table. Triggers are usually used to implement a complex chain of logic. If it's a straight insert or update then keep simple and use a proc.
If it's just an insert, then the quickest way of all is a bulk insert.
Since you want to keep the previous state, my advice would be to create an archive/audit table (basically a duplicate, with possibly some extra fields like WhenInserted etc), on insert move (i.e. insert in the new table and then delete from the original) the existing rows into the archive and then you can do a bulk insert for the new rows.
But you use the word "change", so it's difficult to know what you really want. Hope that helps.
I'm currently writing a posting website that needs to have a version control on posts. I just don't know how I should implement this, in term of database and technique, in order to save and control the post.
Is there anyone experienced with this who can help me?
I've seen that Wordpress does version control only in 1 table, which is POST. I also suggest doing the same since it's trouble to write into 2 tables with the same amount of data and fields.
I know that stackoverflow stores deltas between versions. What I have seen others do is set up another table like the first one but with an author and a version or timestamp on it. You can push records over to the other table using a database trigger so you don't have to worry too much about making the change at the application level.
If you would like to use only one table then I would suggest adding the author, timestamp and a iscurrent flag. The flag isn't really needed since you can select the max version number but it will make your queries much easier. Set the flag only when the row is the highest version number. You can still use a trigger to populate the rows but watch out or you might end up in a loop of update triggers.
I would create two tables, one is "live version" table and the other is an "archive" table. When a new version is created, move the existing live version to the archive table (with appropriate timestamps and author notes) and add the new live version to the live table.
The archive table would have the same schema as the live table except that it would also have additional columns that would hold metadata about the versioning that you are supporting (version number, notes, timestamps, etc.).
Take this with a huge grain of salt, but, you could have a parent id that is joined to the primary key on the same table along with a bool that indicates whether its the current version. It's the method I used for a CMS system a while back... You might want a common id for a revision history (so that getting all historic entries for an item is non recursive). You could do this by including the first version's id with the all the subsequent versions so you could get the whole lot easily.
my .02
Sounds like you just want a record version number on the row. It's a number that identifies the latest version. Every time you update the data you actually insert a new row and bump the record version number. When you query to get the data, you just query to get the row with the max record version number. Triggers can be used to generate the record version number so you don't have to worry about generating the number when inserting.
If you want to go full-blown version control, you need some sort of status field on the row as well that tells you if this version is reverted/deleted/approved or not. When you get the latest, you select the the row with the max revision control number that has the appropriate status.
If you just want to save the history of the posts and not actually have revision control you can just use the record version number technique.
See also Implementing Version Control of DB Objects.