简体   繁体   中英

How to update sql server timestamp column without changing record data

I have an sql server table with a timestamp column. Is there a way to force the timestamp column to change without an actual update of the record?

The reason I am asking is because I want the record's timestamp to change when a record is inserted/updated/deleted in a child table.

Timestamp may not be the best way to go about doing this. If not, what should I do? I don't want to use datetime because I don't feel that's a good way of versioning. I don't want to use an integer, because I don't want to have to read the value to increment it.

Suggestions?

I don't want to use an integer, because I don't want to have to read the value to increment it.

UPDATE Table SET
    IntColumn = IntColumn + 1

While that does technically require a read, I don't see any problems with it.

You could always just update to the same value:

UPDATE Table SET
    SomeColumn = SomeColumn

which will trigger rowversion update as well.

ADDITION: You could do a view with the max rowversion of the children:

SELECT Parent.*, MaxChildRowVersion as ChildVersion
FROM Parent
JOIN (
    SELECT ParentId, MAX(RowVersion) as MaxChildRowVersion
    FROM Child
    GROUP BY ParentId
) as Child ON
     Parent.ParentId = Child.ParentId

But, no, you can't directly update a rowversion column (though you could implement your own updatable with @@DBTS, binary(8) and INSTEAD OF triggers...)

Could you give examples of your last point? It sounds promising.

No, really it doesn't. ;) It's too much work when you could just update to the same value instead or use a view. Those are the 2 easiest options.

But, to be complete, a binary(8) column with a default of @@DBTS (which returns the database version number), and an AFTER UPDATE trigger that also updates the binary column to the new @@DBTS will give you a psuedo-rowversion type that you can then update manually. It'd be no faster or better than just updating some other column to it's same value though.

Ronnie,

First of all the timestamp syntax is being deprecated by Microsoft, so you need to use rowversion , second the rowversion is always related to the row.

From the documentation:

rowversion

Each database has a counter that is incremented for each insert or update operation that is performed on a table that contains a rowversion column within the database. This counter is the database rowversion .

However, because the way it's implemented in SQL server, you need to use triggers to achieve what you want.

Something like this:

CREATE TRIGGER tgUpdateParentRowVersion ON ChildTable FOR INSERT, DELETE, UPDATE
AS
BEGIN
   /*
    * The updates below force the update of the parent table rowversion
    */
   UPDATE ParentTable
      SET ChildUpdate = ChildUpdate + 1
     FROM ParentTable a 
     JOIN inserted    i on a.pkParentTable = i.fkParentTable

   UPDATE ParentTable
      SET ChildUpdate = ChildUpdate - 1
     FROM ParentTable a 
     JOIN deleted     d on a.pkParentTable = d.fkParentTable
END

Believe it or not, this updates a RowVersion/Timestamp column without setting a column. Notice @foo=@foo is the only clause after set . I'm using Sql Server 2017.

declare @foo nvarchar(50);

update dbo.MyTable
set @foo = @foo
where Id = @id

Have you looked into using triggers ? It seems a more natural fit for what you're after.

I worked on an application that had timestamps across the board once upon a time; exactly what we were supposed to do with them proved to be kind of elusive so we audited them out of the schema. You could read timestamp in to objects you create based off of the data and check to see if it's changed when you go to update and rollback if you see that the data's dirty, but that's a lot of boilerplate for not a lot of gain (at least in the domain I was working in).

What I am going to do, until a better idea comes along, is to add a DateTime column to my parent table called DateChildrenChanged.

I will add a trigger on the child table that will set the DateChildrenChanged column to the current DateTime and when that happens, the timestamp column on the parent table will also be updated.

This way I'm using the timestamp column for versioning.

I'm still very open to ideas.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM