473,406 Members | 2,867 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Checksum not working

I'm developing a stored procedure to run an update based on values
entered into a .Net web form. I want to capture the chceksum of the
row when it is displayed on the form then validate that when the update
is exec'd. Simple enough logic, eh? The problem is when I try to use
the checksum(*) function, SQL server yells at me and says that it isn't
recognized. I'm using SQL Server 7, so wtf? I am not the admin of the
server and I'm skirting around SQL Server Enterprise Manager and using
any free utils, MS Access, and Visual Studio to maintain this db.
Thanks
Alex Jamrozek

Jul 23 '05 #1
7 2297
The CHECKSUM function is specific to SQL Server 2000. It doesn't exist
in 7.0.

It seems like you are trying to implement optimistic locking on your
form. For that you can use a TIMESTAMP column in your table to
determine whether the data has changed.

--
David Portas
SQL Server MVP
--

Jul 23 '05 #2
Thanks David.
I'm somewhat of a noob to SQL Server. I thought 7.0 supported that.
So let me see if I understand this TIMESTAMP logic. I would update the
row's TIMESTAMP column to GetDate() whenever the row was accessed, then
check that value again when the web form exec's its update. If it's not
the same as it was when the row was originally accessed, then the web
form's update should fail. Does this sound right?

Jul 23 '05 #3
TIMESTAMP is just a binary value, not a date and time, and it can't be
updated directly, it just increments whenever the row is updated. What
you have to do is retrieve the TIMESTAMP when you read the row and then
compare to the current value in the table before you do the update. If
the two values are different then the row has been updated.

Be aware that a different TIMESTAMP doesn't necessarily mean the row's
*data* has changed - an update might have touched the row but just
replaced a value with the original value. Typically that isn't much of
a problem because the situation is fail-safe - you'll block an update
that might have been valid rather than allow an update against dirty
data. CHECKSUM in SQL Server 2000 is a different matter. It isn't a
reliable way to implement optimistic locking because it's perfectly
possible (in fact it's quite common) for two *different* sets of values
to give the *same* CHECKSUM value.

The only way to detect for certain if data has changed is to compare
every retrieved value with the columns in the table. You can do this in
a stored procedure by passing both the old and new values as
parameters. The following works assuming none of the columns is
nullable:

BEGIN TRAN

UPDATE YourTable
SET
col1 = @new_col1,
col2 = @new_col2,
col3 = @new_col3
WHERE
col1 = @old_col1
col2 = @old_col2
col3 = @old_col3

IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN
RAISERROR('Concurrency error',16,1)
ELSE
COMMIT TRAN
END

Hope this helps.

--
David Portas
SQL Server MVP
--

Jul 23 '05 #4
On 31 Mar 2005 11:10:14 -0800, ajamrozek wrote:
Thanks David.
I'm somewhat of a noob to SQL Server. I thought 7.0 supported that.
So let me see if I understand this TIMESTAMP logic. I would update the
row's TIMESTAMP column to GetDate() whenever the row was accessed, then
check that value again when the web form exec's its update. If it's not
the same as it was when the row was originally accessed, then the web
form's update should fail. Does this sound right?


Hi Alex,

Actually, no. You never update the timestamp column. SQL Server will
change it's value whenever the row is inserted or updated. All you need
to do is to store the value from the timestamp column when you read the
data, then check if it is unchanged when you do the update. Somthing
like this:

SELECT @Var1 = Col1, @Var2 = Col2, ..., @TSvalue = TSColumn
FROM YourTable
WHERE KeyCol = @KeySelected

(Do things with the data - probably including showing it to the end user
and waiting for input)

UPDATE YourTable
SET Col1 = @Var1, @Col2 = @Var2, ...
WHERE KeyCol = @KeySelected
AND TSColumn = @TSValue
IF @@ROWCOUNT = 1
BEGIN
RAISERROR ('The row has been changed - update refused', 16, 1)
RETURN -1
END
(Note - the name timestamp is misleading. The values stored have no
relation at all with date and/or time of update. Since SQL Server 2000,
the datatype rowversion has been added as an alias to timestamp. I hope
that MS will decide to drop the old timestamp name in a future version).

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Jul 23 '05 #5
Thanks both to David and Hugo. You guys have educated me greatly.

Jul 23 '05 #6
Ok so here's my stored procedure:
--------------------------------------
(
@NSIR_ID INT,
@PRODUCT_DESCRIPTION NVARCHAR(255),
@ACCESS_TIMESTAMP TIMESTAMP
)
AS
BEGIN TRAN

UPDATE ajamroz.IT_NSIR
SET PRODUCT_DESCRIPTION = @PRODUCT_DESCRIPTION
WHERE ID = @NSIR_ID AND ACCESS_TIMESTAMP = @ACCESS_TIMESTAMP

IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN
SELECT 'NSIR: ' + CAST(@NSIR_ID AS NVARCHAR(5)) + ' has changed since
you opened it, so your changes could not be recorded. Please close
this window and select the record again to get the latest changes.'
END
ELSE
COMMIT TRAN
----------------------------------
All updates are still executing though. I tried to make this thing
throw the error and it didn't. It seems like @@ROWCOUNT is never 0.

Jul 23 '05 #7
On 31 Mar 2005 14:17:10 -0800, ajamrozek wrote:
Ok so here's my stored procedure:
--------------------------------------
(
@NSIR_ID INT,
@PRODUCT_DESCRIPTION NVARCHAR(255),
@ACCESS_TIMESTAMP TIMESTAMP
)
AS
BEGIN TRAN

UPDATE ajamroz.IT_NSIR
SET PRODUCT_DESCRIPTION = @PRODUCT_DESCRIPTION
WHERE ID = @NSIR_ID AND ACCESS_TIMESTAMP = @ACCESS_TIMESTAMP

IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN
SELECT 'NSIR: ' + CAST(@NSIR_ID AS NVARCHAR(5)) + ' has changed since
you opened it, so your changes could not be recorded. Please close
this window and select the record again to get the latest changes.'
END
ELSE
COMMIT TRAN
----------------------------------
All updates are still executing though. I tried to make this thing
throw the error and it didn't. It seems like @@ROWCOUNT is never 0.


Hi Alex,

I tried it, but I had no problems. Here is the code I used.

First, the part to set up the table and procedure. Note that I simply
copied your stored procedure; the only change was to remove the owner
(ajamroz.) in fronn of the table name.

drop table IT_NSIR
go
create table IT_NSIR
(ID int NOT NULL,
PRIMARY KEY (ID),
PRODUCT_DESCRIPTION nvarchar(255) NOT NULL,
ACCESS_TIMESTAMP timestamp NOT NULL)
go
drop proc UpdateProc
go
create proc UpdateProc
(
@NSIR_ID INT,
@PRODUCT_DESCRIPTION NVARCHAR(255),
@ACCESS_TIMESTAMP TIMESTAMP
)
AS
BEGIN TRAN

-- UPDATE ajamroz.IT_NSIR
UPDATE IT_NSIR
SET PRODUCT_DESCRIPTION = @PRODUCT_DESCRIPTION
WHERE ID = @NSIR_ID AND ACCESS_TIMESTAMP = @ACCESS_TIMESTAMP

IF @@ROWCOUNT = 0
BEGIN
ROLLBACK TRAN
SELECT 'NSIR: ' + CAST(@NSIR_ID AS NVARCHAR(5)) + ' has changed since
you opened it, so your changes could not be recorded. Please close
this window and select the record again to get the latest changes.'
END
ELSE
COMMIT TRAN
go
insert IT_NSIR (ID, PRODUCT_DESCRIPTION)
select 1, 'Test row'
go
With the table and stored procedure created, I executed this code from
Query Analyzer window #1:

-- Check starting information
select * from IT_NSIR
go
declare @NSIR_ID INT,
@PRODUCT_DESCRIPTION NVARCHAR(255),
@ACCESS_TIMESTAMP TIMESTAMP
-- Choose a row to operate on
set @NSIR_ID = 1
-- Simulate the read
select @PRODUCT_DESCRIPTION = PRODUCT_DESCRIPTION,
@ACCESS_TIMESTAMP = ACCESS_TIMESTAMP
from IT_NSIR
where ID = @NSIR_ID
-- Simulate "human activity"
waitfor delay '00:00:15' -- 15 seconds delay
set @PRODUCT_DESCRIPTION = 'Updated info'
-- Try the update
exec UpdateProc @NSIR_ID,
@PRODUCT_DESCRIPTION,
@ACCESS_TIMESTAMP
-- Review the result
select * from IT_NSIR
During the 15 seconds delay, I switched to Query Analyzer window #2 and
executed this code (to simulate an update by another user):

UPDATE IT_NSIR
SET PRODUCT_DESCRIPTION = 'Updated by someone else'
WHERE ID = 1
After the 15 seconds delay were finished, the output in window #1 was:

ID PRODUCT_DESCRIPTION ACCESS_TIMESTAMP
----------- ---------------------------- ------------------
1 Test row 0x000000000000721D
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
NSIR: 1 has changed since
you opened it, so your changes could not be recorded. Please close
this window and select the record again to get the latest changes.

ID PRODUCT_DESCRIPTION ACCESS_TIMESTAMP
----------- ---------------------------- ------------------
1 Updated by someone else 0x000000000000721E
I then re-executed the query in window #1, but this time I let it run
without executing any other query, The results were:

ID PRODUCT_DESCRIPTION ACCESS_TIMESTAMP
----------- ---------------------------- ------------------
1 Updated by someone else 0x000000000000721E

ID PRODUCT_DESCRIPTION ACCESS_TIMESTAMP
----------- ---------------------------- ------------------
1 Updated info 0x000000000000721F

(Note: I have edited the output above a little - I have removed most of
thhe white space of the product_description column to improve
readability)

Best, Hugo
--

(Remove _NO_ and _SPAM_ to get my e-mail address)
Jul 23 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Mercuro | last post by:
Hello i'm looking for a simple way to checksum my data. The data is 70 bytes long per record, so a 32 byte hex md5sum would increase the size of my mysql db a lot. I'm looking for something...
3
by: wilk | last post by:
I have a problem witch calculating TCP or UDP checksum. This is what I found: u16 in_cksum(u16 *addr,int count) { register long sum = 0; /* add 16-bit words */ while (count > 1) { /* this...
2
by: pradeep | last post by:
I have 2 data files, DATA1 and DATA2 , both same. My task is to: Open DATA1, compute the checksum and put it in the end of the file(don't bother about boundary conditions).close DATA1 Open...
2
by: Abby | last post by:
I need to do 8 bits 2's complement checksum, so I wrote code in order to see if the checksum calculation is correct. ===========================================================================...
1
by: Terry | last post by:
I'm trying to calculate the checksum for UDP packet. The algorithm itself is not difficult (lots of examples out there), but what I'm having the most trouble with is determining the byte order...
24
by: Bob | last post by:
Hi there, I am working on an application to be used in our local Forensics department... Among other things the app will connect to a digital camera and download the images to the hard drive....
15
by: ValK | last post by:
Hello, I’m working with handheld device that communicates with windows service thru the serial port. Transaction between device and my application looks like this: Handshaking: Device sends ...
4
by: Rain | last post by:
hi, need help here, does anyone know how to use or does any one have the code for checksum? I want to checksum a string to be sent using udp and checksum it again when received.. does anyone...
0
by: gajjar123 | last post by:
hi , i m trying to generate MD5 checksum (32 char) for xml file or other file using string Result ; Result=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str,...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.