473,386 Members | 1,715 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,386 software developers and data experts.

Selecting Unique Record

I have a stored procedure (below), that is suppose
to get a Reg Number from a table, (Reg_Number), in
such a way that every time the stored procedure is called,
it will get a different reg number, even if the stored
procedure is called simultaneously from two different
places,

However it is not working that way.

If two different users access a function in there
VB program at the same time, the two different users
will get the same reg number.

I have looked at the stored procedure, it looks foolproof,
yet it is not working that way.

Thanks in Advance,

Laurence Nuttall
Programmer Analyst III
UCLA - Division of Continuing Education

'---------------------------------------------------------------------------


Here it is:

CREATE PROCEDURE sp_GetNextRegNum
@newRegNum char(6) = NULL OUTPUT
AS
LABEL_GET_ANOTHER_REG:

Select @newRegNum =(select min(Reg) from reg_number)

IF Exists (select Reg from reg_number where reg = @newRegNum )

Begin
Delete from reg_number where reg = @newRegNum

IF @@Error <> 0
Begin
Goto LABEL_GET_ANOTHER_REG
End
--Endif
End

ELSE
GoTo LABEL_GET_ANOTHER_REG
--Endif
GO
Jul 20 '05 #1
6 1412
Create a dummy table with an identity column and a non-identity column; have
the sproc insert a dummy row; have the sproc return SCOPE_IDENTITY()

"Larry" <Bl***@Bliff.com> wrote in message
news:cb**********@daisy.noc.ucla.edu...
I have a stored procedure (below), that is suppose
to get a Reg Number from a table, (Reg_Number), in
such a way that every time the stored procedure is called,
it will get a different reg number, even if the stored
procedure is called simultaneously from two different
places,

However it is not working that way.

If two different users access a function in there
VB program at the same time, the two different users
will get the same reg number.

I have looked at the stored procedure, it looks foolproof,
yet it is not working that way.

Thanks in Advance,

Laurence Nuttall
Programmer Analyst III
UCLA - Division of Continuing Education

'---------------------------------------------------------------------------

Here it is:

CREATE PROCEDURE sp_GetNextRegNum
@newRegNum char(6) = NULL OUTPUT
AS
LABEL_GET_ANOTHER_REG:

Select @newRegNum =(select min(Reg) from reg_number)

IF Exists (select Reg from reg_number where reg = @newRegNum )

Begin
Delete from reg_number where reg = @newRegNum

IF @@Error <> 0
Begin
Goto LABEL_GET_ANOTHER_REG
End
--Endif
End

ELSE
GoTo LABEL_GET_ANOTHER_REG
--Endif
GO

Jul 20 '05 #2
The trick is to use a transaction and a serializable isolation level.

That is the first code I have seen with GOTO statements in over 15
years! Did you mean to put a "sp_" prefix on the code?

Could I suggest that instead of deleting the reg numbers as they are
issued, that you update the table to show the date and time they are
issued? No sense losing information and the ability to re-construct a
history. Might want to add the user info, too. Something like this:

CREATE PROCEDURE GetNextRegnum
@newregnum CHAR(6) OUTPUT
AS
BEGIN TRANS
SET @newregnum
=(SELECT MIN(reg)
FROM RegNumbers
WHERE issue_date IS NULL);
UPDATE RegNumbers
SET issue_date = CURRENT_TIMESTAMP
WHERE reg = @newregnum;
<< error handling, commit, rollback here >>
END;

--CELKO--
===========================
Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, datatypes, etc. in your
schema are.

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 20 '05 #3
Joe,

The stored procedure was written years ago by someone
who is long gone. I inherited it.

For new stored procedures we now know to prefix them with
something other than "sp_"

I know what a transaction is, I am trying to understand what
"serializable isolation level" is.

Someone suggested that I do this:

begin tran
Select @newRegNum = (Select min(Reg) from reg_number with
updlock,rowlock)

I am not sure about how to configure the transaction,
As this stored procedure is being called from another
stored procedure, at a point in the calling stored procedure
when another transaction is active.

Thank You,

Laurence Nuttall
Programmer Analyst III
UCLA - Division of Continuing Education

'-------------------------------

Here is the DDL for the table:

if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[Reg_Number]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Reg_Number]
GO

CREATE TABLE [dbo].[Reg_Number] (
[Reg_Number_ID] [int] NOT NULL ,
[Reg] [char] (6) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Login] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Modified_date] [smalldatetime] NULL ,
[Concurrent_use] [tinyint] NULL
) ON [PRIMARY]
GO

'---------------------------------------------------------------------------------------------------------------

Joe Celko wrote:
The trick is to use a transaction and a serializable isolation level.

That is the first code I have seen with GOTO statements in over 15
years! Did you mean to put a "sp_" prefix on the code?

Could I suggest that instead of deleting the reg numbers as they are
issued, that you update the table to show the date and time they are
issued? No sense losing information and the ability to re-construct a
history. Might want to add the user info, too. Something like this:

CREATE PROCEDURE GetNextRegnum
@newregnum CHAR(6) OUTPUT
AS
BEGIN TRANS
SET @newregnum
=(SELECT MIN(reg)
FROM RegNumbers
WHERE issue_date IS NULL);
UPDATE RegNumbers
SET issue_date = CURRENT_TIMESTAMP
WHERE reg = @newregnum;
<< error handling, commit, rollback here >>
END;

--CELKO--
===========================
Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, datatypes, etc. in your
schema are.

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!

Jul 20 '05 #4
A fellow worker just pointed at that:

The @@Error will be zero, even if the
delete could not find a record to delete,

That is:

Delete from reg_number where reg = @newRegNum
IF @@Error <> 0

The if statment will never be true, that is
the @@ERROR will never be non zero.

Is this true?, if so then this stored procedure
never worked at all.

Thanks in Advance,

Larry

Joe Celko wrote:
The trick is to use a transaction and a serializable isolation level.

That is the first code I have seen with GOTO statements in over 15
years! Did you mean to put a "sp_" prefix on the code?

Could I suggest that instead of deleting the reg numbers as they are
issued, that you update the table to show the date and time they are
issued? No sense losing information and the ability to re-construct a
history. Might want to add the user info, too. Something like this:

CREATE PROCEDURE GetNextRegnum
@newregnum CHAR(6) OUTPUT
AS
BEGIN TRANS
SET @newregnum
=(SELECT MIN(reg)
FROM RegNumbers
WHERE issue_date IS NULL);
UPDATE RegNumbers
SET issue_date = CURRENT_TIMESTAMP
WHERE reg = @newregnum;
<< error handling, commit, rollback here >>
END;

--CELKO--
===========================
Please post DDL, so that people do not have to guess what the keys,
constraints, Declarative Referential Integrity, datatypes, etc. in your
schema are.

*** Sent via Devdex http://www.devdex.com ***
Don't just participate in USENET...get rewarded for it!

Jul 20 '05 #5
Joe Celko (jc*******@earthlink.net) writes:
The trick is to use a transaction and a serializable isolation level.
But since the default on SQL Server is READ COMMITTED, you must specify
that you need serializable. Thus you suggestion does not fly:
CREATE PROCEDURE GetNextRegnum
@newregnum CHAR(6) OUTPUT
AS
BEGIN TRANS
SET @newregnum
=(SELECT MIN(reg)
FROM RegNumbers
WHERE issue_date IS NULL);
UPDATE RegNumbers
SET issue_date = CURRENT_TIMESTAMP
WHERE reg = @newregnum;
<< error handling, commit, rollback here >>
END;
You must say SET TRANSACTION ISOLATION LEVEL SERIALIZABLE first, or else
two simultaneous callers can get the same @newregnum. Using UPDLOCK as
Larry said in his later posting is also good.

Note that whatever the method, if there are two parallel calls, then
the second caller will be blocked until the first commits this transaction.
(Larry said that this procedure is part of a outside transaction.)
Could I suggest that instead of deleting the reg numbers as they are
issued, that you update the table to show the date and time they are
issued? No sense losing information and the ability to re-construct a
history. Might want to add the user info, too. Something like this:
Indeed a good suggestion. Just make sure that there is an index on
(index_date, reg).
That is the first code I have seen with GOTO statements in over 15
years!


Hey! I use GOTO in my code occasionally. (Mainly for error exits.)

--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #6
Larry (Bl***@Bliff.com) writes:
A fellow worker just pointed at that:

The @@Error will be zero, even if the
delete could not find a record to delete,
Yes. Not find a matching row is not an error, but a perfectly normal thing.
That is:

Delete from reg_number where reg = @newRegNum
IF @@Error <> 0

The if statment will never be true, that is
the @@ERROR will never be non zero.


Well, @@error could be non-zero for other reasons, for instance a
constraint violation, or a lock timeout.
--
Erland Sommarskog, SQL Server MVP, es****@sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #7

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

Similar topics

7
by: Tony Clarke | last post by:
Hi, I'm trying to write a system thats used for about 50 clients that uses html forms and php to log details. The problem is that when a client loads the form page it's given a value which is...
19
by: Ben Gribaudo | last post by:
Hello! I am trying to query a MySQL table and retrieve either the earliest or the latest message in each thread. The messages are in a table with MsgID being the primary key and fThreadID...
6
by: throat.wobbler.mangrove | last post by:
Hi, I was hoping someone may be able to help me with a tricky T-SQL problem. I need to come up with a SELECT statement that does basically the following: Select RCRD_REFNO, MAX(MODIF_DTTM)...
3
by: Phil | last post by:
I am looking to set up a hyperlink control on a form to retrieve letters that correspond to a record on a form. That is, there may be 100 form records, and I would like each of those form records...
8
by: Henrik Larsson | last post by:
Hi, I need help with selecting the following rows from a table looking like this: ID IP Query 1 -> 1 2.2.2.2 (ie first IP 1 1.1.1.1 <- Query 2 for each...
48
by: phillip.s.powell | last post by:
MySQL 3.23.58 - 4.0.17 (yep, several database server instances, don't ask) I have database Spring with table Students I have database Summer with table Students I am tasked to produce a...
0
by: steve | last post by:
Hi all, Come across a situation I cannot figure how to work out. Im relatively new to access but have looked around and tried everything to my knowledge. I've developed an application whereby...
3
by: Channel05 | last post by:
Hi everyone, I'm having a problem writing out the SQL statement and unfortunately, I can't even produce you a working draft version simply because I cannot wrap my head around how to start it. I...
2
by: ljayz | last post by:
hello guys is there a way to fetch a record having 2 or more unique id in one declaration? ive tried this code "select * from table where id = '1' and id = '2' order by id" but gave me no records...
8
by: douglevin | last post by:
I have a table that has 3 columns: filePath, filePrefix, timestamp. I need a query that will return the most current filePath of records with a unique filePrefix. For example, say there are...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
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?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

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.