Reputation: 527
I have an update procedure as follows:
UPDATE Repairs
SET TypeID = CASE WHEN @TypeID IS NULL THEN TypeID ELSE @TypeID END,
Directions = CASE WHEN @Directions IS NULL THEN Directions ELSE @Directions END,
LastUpdate = SYSDATETIME()
WHERE RepairID = @RepairID
I don't have a concurrency concern but Directions
can be a pretty long NVarChar
string. Is SQL Server smart enough not to copy the existing data onto itself or should I look for another approach?
Upvotes: 0
Views: 67
Reputation: 8687
Is SQL Server smart enough not to copy the existing data onto itself Yes it is smart enough.
When you modify a row, SQL Server logs only a modified bytes, so when for example you change an int value from 1 to 24, SQL Server modifies only 1 byte of 4 (int value is 4 bytes long)
The change made can be written to log in two ways, as LOP_MODIFY_ROW
or as LOP_MODIFY_COLUMNS
, but anyway if your nvarchar value is not changed, only fixed-length part of the row will be logged (other fields you change are of fixed-length types)
It could be different in case your string was nchar(not nVARchar), in this case the order of columns in table definition matters.
And in case you did not modify LastUpdate too, there would be nothing logging at all.
If your question is not about logging but about data pages, of course if there is any change to a row (and you always modify at least LastUpdate field), the page immediately is marked as dirty page. This means that this page is different from what is stored on disk and the next checkpoin operation will write it to disk.
SQL Server is not writing every modified row to disk, the minimum amount of data that can be written to disk is a page(8Kb), but it's not immediately written to disk as soon as it was modified, it's checkpoint instead(ok, or eager writer, or lazy writer to be precise) to write dirty pages to disk periodically.
Upvotes: 2
Reputation: 14077
This could be rewritten as follows:
UPDATE Repairs
SET
TypeID = ISNULL(@TypeID, TypeID),
Directions = ISNULL(@Directions, Directions),
LastUpdate = SYSDATETIME()
WHERE RepairID = @RepairID;
But it's not going to make any noticeable difference. If it's just these few columns, you then might have three separate cases to make these updates:
IF @TypeID IS NOT NULL
AND @Directions IS NOT NULL
UPDATE Repairs
SET
TypeID = ISNULL(@TypeID, TypeID),
Directions = ISNULL(@Directions, Directions),
LastUpdate = SYSDATETIME()
WHERE RepairID = @RepairID;
ELSE IF @TypeID IS NOT NULL
UPDATE Repairs
SET
TypeID = ISNULL(@TypeID, TypeID),
LastUpdate = SYSDATETIME()
WHERE RepairID = @RepairID;
ELSE IF @Directions IS NOT NULL
UPDATE Repairs
SET
Directions = ISNULL(@Directions, Directions),
LastUpdate = SYSDATETIME()
WHERE RepairID = @RepairID;
ELSE
THROW 51000, 'Nothing to update mate!', 1;
But I doubt that this is going to make any significant difference too. It just adds too much boilerplate to your code. Keep with what you have or ISNULL()
s
Upvotes: 1