Is there any way to update the modified date time automatically in SQL Server? - sql-server

Is there any way to update the modified date time automatically in SQL Server.
I do not want to use Triggers. Also I want to avoid providing the value through application while calling SQL query.
Is there any support in SQL or in Dapper etc.

If you want to keep track of the changes in database you can use a feature called
System-Versioned Temporal Table as explained here.
Using a Temporal Table, you will be able to query the recent state of the row as usual, in addition to the ability to query the full history of that row
It's very handy if you are interested in keeping a history of data changes

I am able to solve the problem using Temporal Table. I am not sure is this a elegant solution. Here is how i solved.
Create Table:
CREATE TABLE extable4 (PriKey int PRIMARY KEY, ColValue varchar(200)
, [ModifiedDateTime] datetime2 (2) GENERATED ALWAYS AS ROW START
, [ModifiedExpiryDateTime] datetime2 (2) GENERATED ALWAYS AS ROW END HIDDEN
, PERIOD FOR SYSTEM_TIME (ModifiedDateTime,[ModifiedExpiryDateTime])
) ;
Insert a record with out providing input to ModifiedDatetime.
insert into extable4(PriKey,ColValue) values(1,'Ver 1');
ModifiedDateTime Populated with systime.
update extable4 set ColValue='Ver 1.1' where PriKey=1;
ModifiedDateTime updated now. :)

Related

Creating a history table without using triggers

I have a TABLE A with 3000 records with 25 columns. I want to have a history table called Table A history holding all the changes updates and deletes for me to look up any day. I usually use cursors. Now thought using triggers which I was not asked to. Do you have any other suggestions? Many thanks!
If your using tsql /SQL server and you can't use triggers, which is the only sure way to get every change, maybe use a stored procedure that is scheduled in job to run every x amount of time, the stored procedure using a MERGE statement with the two tables to get new records or changes. I would not suggest this if you need every single change without question.
CREATE TABLE dbo.TableA (id INT, Column1 nvarchar(30))
CREATE TABLE dbo.TableA_History (id INT, Column1 nvarchar(30), TimeStamp DateTime)
(this code isn't production, just the general idea)
Put the following code inside a stored procedure and use a Sql Server Job with a schedule on it.
MERGE INTO dbo.TableA_History
USING dbo.TableA
ON TableA_History.id = TableA.id AND TableA_History.Column1 = TableA.Column1
WHEN NOT MATCHED BY TARGET THEN
INSERT (id,Column1,TimeStamp) VALUES (TableA.id,TableA.Column1,GETDATE())
So basically if the record either doesn't exist or doesn't match meaning a column changed, insert the record into the history table.
It is possible to create history without triggers in some case, even if you are not using SQL Server 2016 and system-versioned table are not available.
In some cases, when you can identify for sure which routines are modifying your table, you can create history using OUTPUT INTO clause.
For example,
INSERT INTO [dbo].[MainTable]
OUTPUT inserted.[]
,...
,'I'
,GETUTCDATE()
,#CurrentUserID
INTO [dbo].[HistoryTable]
SELECT *
FROM ... ;
In routines, when you are using MERGE I like that we can use $action:
Is available only for the MERGE statement. Specifies a column of type
nvarchar(10) in the OUTPUT clause in a MERGE statement that returns
one of three values for each row: 'INSERT', 'UPDATE', or 'DELETE',
according to the action that was performed on that row.
It's very handy that we can add the user which is modifying the table. Using triggers you need to use session context or session variable to pass the user. In versioning table you need to add additional column to the main table in order to log the user as it only logs the current table columns (at least for now).
So, basically it depends on your data and application. If you have many sources of CRUD over the table, the trigger is the most secure way. If your table is very big and heavily used, using MERGE is not good as it my cause blocking and harm performance.
In our databases we are using all of the methods depending on the situation:
triggers for legacy
system-versioning for new development
direct OUTPUT in the history, when sure that data is modified only by given set of routines

Trigger to log inserted/updated/deleted values SQL Server 2012

I'm using SQL Server 2012 Express and since I'm really used to PL/SQL it's a little hard to find some answers to my T-SQL questions.
What I have: about 7 tables with distinct columns and an additional one for logging inserted/updated/deleted values from the other 7.
Question: how can I create one trigger per table so that it stores the modified data on the Log table, considering I can't used Change Data Capture because I'm using the SQL Server Express edition?
Additional info: there is only two columns in the Logs table that I need help filling; the altered data from all the columns merged, example below:
CREATE TABLE USER_DATA
(
ID INT IDENTITY(1,1) NOT NULL,
NAME NVARCHAR2(25) NOT NULL,
PROFILE INT NOT NULL,
DATE_ADDED DATETIME2 NOT NULL
)
GO
CREATE TABLE AUDIT_LOG
(
ID INT IDENTITY(1,1) NOT NULL,
USER_ALTZ NVARCHAR(30) NOT NULL,
MACHINE SYSNAME NOT NULL,
DATE_ALTERERED DATETIME2 NOT NULL,
DATA_INSERTED XML,
DATA_DELETED XML
)
GO
The columns I need help filling are the last two (DATA_INSERTED and DATA_DELETED). I'm not even sure if the data type should be XML, but when someone either
INSERTS or UPDATES (new values only), all data inserted/updated on the all columns of USER_DATA should be merged somehow on the DATA_INSERTED.
DELETES or UPDATES (old values only), all data deleted/updated on the all columns of USER_DATA should be merged somehow on the DATA_DELETED.
Is it possible?
Use the inserted and deleted Tables
DML trigger statements use two special tables: the deleted table and
the inserted tables. SQL Server automatically creates and manages
these tables. You can use these temporary, memory-resident tables to
test the effects of certain data modifications and to set conditions
for DML trigger actions. You cannot directly modify the data in the
tables or perform data definition language (DDL) operations on the
tables, such as CREATE INDEX. In DML triggers, the inserted and
deleted tables are primarily used to perform the following: Extend
referential integrity between tables. Insert or update data in base
tables underlying a view. Test for errors and take action based on the
error. Find the difference between the state of a table before and
after a data modification and take actions based on that difference.
And
OUTPUT Clause (Transact-SQL)
Returns information from, or expressions based on, each row affected
by an INSERT, UPDATE, DELETE, or MERGE statement. These results can be
returned to the processing application for use in such things as
confirmation messages, archiving, and other such application
requirements. The results can also be inserted into a table or table
variable. Additionally, you can capture the results of an OUTPUT
clause in a nested INSERT, UPDATE, DELETE, or MERGE statement, and
insert those results into a target table or view.
Just posting because this is what solved my problem. As user #SeanLange said in the comments to my post, he said to me to use an "audit", which I didn't know it existed.
Googling it, led me to this Stackoverflow answer where the first link there is a procedure that creates triggers and "shadow" tables doing sort of what I needed (it didn't merge all values into one column, but it fits the job).

How to use TIMESTAMP option in sybase

Hope all are doing great,
I want to create a table in sybase database and the table should have a column with current system time, So i plan to go with TIMESTAMP datatype.
But it not let me to create the table, tried with different way of declaring.
So please provide me a simple table creation with timestamp options..
(Note : i dont want to manually insert system time into the column while inserting, it should be auto update the column )
Tried with TIMESTAMP, Default timestamp, current timestamp,, everything i found by surfing..
so please suggest with any simple table creation query..
THanks in advance
According to me Curent Timestamp in Sybase is inserted using GETDATE() rahter than any other method.

Finding out the data a row has been inserted into a table

Is there a way to find out the data a row has been inserted (into a SQL Server 2005, 2008 or 2008 r2) database table? Without setting up auditing (either ootb or custom 3rd party product).
Thanks
You can always create a trigger on that table. Like so:
create trigger InsertNotification
on YourTable
after insert
as
-- do whatever you want when an insert happens
go
This can definitely be seen as a form of "auditing", but I'm not familiar with "ootb", nor is this a 3rd party product. Triggers are the way to go.
Well if you want to be notified when the row is inserted make insert trigger to this table.
If you just want to save the information when a specific row was inserted, you could just create a new datetime or smalldatetime column with getdate() as the default value.
Whenever a new row is inserted, this column will be automatically filled with the current date/time.
Advantages:
no trigger or 3rd party tool needed
Disadvantages:
this only works for new tables (or all new records in existing tables). If a table already has existing records, you won't have an insert date/time for them
if you want this for all your tables, you have to insert the column into each table

Compute hash-value of entered value when insert or update using sql server 2008 by triggers

I have a table with two columns {FlatContent, HashedContent}. Now I want to automatically compute the hash value of FlatContent when new row was inserted or an existing row was updated. To date, I've never used from trigger, so I can't do this by trigger or another approach which is exist to solve this issue.
Thanks if anybody can help me ;)
Instead of using a trigger, make HashedContent a persisted computed column in your table definition.
ALTER TABLE YourTable
ADD HashedContent AS HashBytes('SHA1', FlatContent) PERSISTED

Resources