Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 How to get nextcounter for each row via a stored p

Author  Topic 

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-23 : 02:53:42
insert into TestJobTable (BookNumber,BookCode,IsActive,SourceId,ContactNumber)
select [exec getnextBooknumber 'Book'],BookCode,'1', @SourceId ,[exec getnextBooknumber 'contact'] from TestBookTableTemp
where SourceId = @SourceId
and BookCode not in
(
select BookCode
from TestBookTable
where SourceId = @SourceId )

Here i have to select records from the temprory table and insert it into actual table.
During insertion I have to execute stored procedure for two columns and get counter for that coumlumn for each row.
What can i do ?
Can any body please give me a solution of my problem even by using cursor

afrika
Master Smack Fu Yak Hacker

2706 Posts

Posted - 2006-12-23 : 03:44:18
many ways to kill a fly, but using a bazooka aint one of them

I believe you are trying to get the last inserted auto increment value from your table ?

if so...

declare @counter int
set @counter = scope_identity()

Read books online
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-23 : 04:14:46
No ,The Problem is not such In my stored procedure I get some custom number.
Any way
I don't think so it will be autoIncremented in my query
I am using insert with select statement.
So If any how i can get the value in some temprory variale how can i increment it for each row and autoincrement it in the select statement column.
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2006-12-24 : 02:04:53
I guess you have to declare the variable, take the value from the stored procedures, before the insert statements and then do the insert statement.

because there is no way you can use Select in the stored procedure.

Check out this link, to see how to get the output parameter in the variable.
http://www.sqlteam.com/item.asp?ItemID=2644



Chirag

http://chirikworld.blogspot.com/
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-26 : 02:03:36
Thanks chiragkhabaria.
Can u please guide me how to use that solution in my scenario
that is

insert into TestJobTable (BookNumber,BookCode,IsActive,SourceId,ContactNumber)
select [exec getnextBooknumber 'Book'],BookCode,'1', @SourceId ,[exec getnextBooknumber 'contact'] from TestBookTableTemp
where SourceId = @SourceId
and BookCode not in
(
select BookCode
from TestBookTable
where SourceId = @SourceId )
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2006-12-26 : 02:19:43
Does GEtNextBookNumber has any output parameter?? can you post the code for this procedure?

Chirag

http://chirikworld.blogspot.com/
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-26 : 02:49:33
Following is my stored procedure [I also have a suggestion to convert it to user defined function.Please also guide me in that]
CREATE PROCEDURE [dbo].[getnextBooknumber]
@CounterType varchar(10)
AS
SET NOCOUNT ON
Declare @CounterValue As Float
Begin Tran
If not exists(Select * From Counter Where CounterType = @CounterType)
Begin
Set @CounterValue = 1
Insert Into Counter (CounterType, CounterValue) Values (@CounterType, @CounterValue)
End
Else
Begin
Select @CounterValue = CounterValue From Counter Where CounterType = @CounterType
Set @CounterValue = @CounterValue + 1
Update Counter Set CounterValue = @CounterValue Where CounterType = @CounterType
End
Commit Tran
SET NOCOUNT OFF
Select CounterValue = @CounterValue
Go to Top of Page

madhivanan
Premature Yak Congratulator

22864 Posts

Posted - 2006-12-26 : 03:02:03
http://sqlteam.com/forums/topic.asp?TOPIC_ID=76821

Madhivanan

Failing to plan is Planning to fail
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2006-12-26 : 03:04:16
I Guess this should help

--Your Stored Procedure
CREATE PROCEDURE [dbo].[getnextBooknumber]
(
@CounterType varchar(10)
)
AS
Begin
SET NOCOUNT ON
Declare @CounterValue As Float
Select @CounterValue = IsNull(Max(CounterValue),0) +1 From Counter Where CounterType = @CounterType
If @CounterValue = 1
Insert Into Counter (CounterType, CounterValue) Values (@CounterType, @CounterValue)
Else
Update Counter Set CounterValue = @CounterValue Where CounterType = @CounterType

SET NOCOUNT OFF
Select CounterValue = @CounterValue

End
GO
--Your Function
Create Function [Dbo].GetNextBookNum
(
@CounterType Varchar(10)
)
As
Begin
Declare @CounterValue As Float
Select @CounterValue = IsNull(Max(CounterValue),0) +1 From Counter Where CounterType = @CounterType
Return @CounterValue
End

--Your Insert Statement
Insert into TestJobTable (BookNumber,BookCode,IsActive,SourceId,ContactNumber)
select Dbo.GETNextBookNum('Book'),BookCode,'1', @SourceId ,Dbo.GETNextBookNum('contact') from TestBookTableTemp
where SourceId = @SourceId
and BookCode not in
(
select BookCode
from TestBookTable
where SourceId = @SourceId
)



Chirag

http://chirikworld.blogspot.com/
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2006-12-26 : 03:20:08
Make sure you call the stored procedure first and then your insert code..., also i believe you dont require a function.. with out function also things can be worked out... like directly calling the value from your counter table

Chirag

http://chirikworld.blogspot.com/
Go to Top of Page

afrika
Master Smack Fu Yak Hacker

2706 Posts

Posted - 2006-12-26 : 05:23:03
Chirag, its xmas !!! Remember

Take a break. Brilliant work
Go to Top of Page

chiragkhabaria
Master Smack Fu Yak Hacker

1907 Posts

Posted - 2006-12-26 : 06:12:37
quote:
Originally posted by afrika

Chirag, its xmas !!! Remember

Take a break. Brilliant work



Well No holidays for me..

Thanks .. Wishing you a Merry Christmas...

Chirag

http://chirikworld.blogspot.com/
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-28 : 06:45:19
I want's to execute getnextBooknumber for each inserted row.
This stored procedure add a record of particular type and then return a parameter which i have to insert into database.
This field should be different for each row.
Please help
Go to Top of Page

afrika
Master Smack Fu Yak Hacker

2706 Posts

Posted - 2006-12-28 : 08:50:51
how many rows are you looking at ?

I also would advice your read up on CSV do a search in this forum

Go to Top of Page

snSQL
Master Smack Fu Yak Hacker

1837 Posts

Posted - 2006-12-28 : 17:23:27
Nothing that you have asked for so far shows that you need this stored procedure.

You want to insert a row into this table and each row should have a new incrementing number, so create an identity column in the table and each row will get a new number automatically. If you want to insert a row that uses the identity value for a row from another table then insert a row into that table, get the last value for that table with scope_identity() and use that value.

You seem determined to call a stored procedure to get the value, rather tell us the specific result you require and we can help you to get there - which I think I (and previous posts) have already told you. The point is that you do not need to keep the counters manually the way you are trying to, SQL Server already does it for you.
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-29 : 01:09:49
Actually I have 4 GB of data in my tables.My existing tables pk is of type float and not the identity fields.
There is one table Counter which maintains these counters for each of my table and return the float which i have to insert into those table.
Previously i were doing some sort of row by row insert.During that i get next counter .But I have around 50 to 60 thousands of records.
So Now I first dump it into a temporary table.Do some more manipulation on that table records data then insert into my actual table.

Please can any body help in this ?
Go to Top of Page

snSQL
Master Smack Fu Yak Hacker

1837 Posts

Posted - 2006-12-29 : 03:04:02
So doing all of that is easier than changing the PK column to int or bigint and making it an identity column?

Here's the reality that none of us can change for you - a SQL Server stored procedure cannot return a value into a SELECT statement, you'd have to execute the stored proc in a separate statement and store the output value in a variable and then use it in your insert. A SQL Server user-defined function can return a value into a SELECT, but a user defined function cannot update data, so that won't work.

So, you either need to change to using an identity, which I'd still say is your best approach, or you need to write a stored proc that inserts the row into the Counter table, and then inserts the row into the TestJobTable using the local counter variable from the Counter insert.
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2006-12-29 : 06:15:33
No work around ?
Could i do it using cursor or any thing ?
Can Any Guru Help me in this ?
Go to Top of Page

snSQL
Master Smack Fu Yak Hacker

1837 Posts

Posted - 2006-12-30 : 17:49:31
No work around ?
I gave you two "workarounds" (actually I thinkk they're good solutions to your problem, not workarounds) - you either need to change to using an identity, which I'd still say is your best approach, or you need to write a stored proc that inserts the row into the Counter table, and then inserts the row into the TestJobTable using the local counter variable from the Counter insert.
Go to Top of Page

Jeff Moden
Aged Yak Warrior

652 Posts

Posted - 2007-01-01 : 00:06:25
Kamii,

My collegues are correct... you should make every effort to use the auto-numbering power of an IDENTITY column and, yes, it was a terrible mistake to make the Primary Keys the FLOAT datatype.

A word of warning... DO NOT USE MAX(COUNTERVALUE)... it WILL eventually bite you with duplicate PK numbers which will cause a failure which will cause a rollback which will cause all sorts of problems.

You must be pretty desperate if you're willing to break down and even think of using a cursor for this...

Your "Counter" table is known by other names... "Sequence Table"... "NextID Table"... all are basically "Death by SQL". Thanks to a 3rd party chunk of garbage software, we have a "NextID" table that used to cause more than 4,000 (NOT a misprint!) deadlocks per day!!! The 3rd party vendor refuses to make the necessary changes and my company refuses to "fire" the 3rd party software because it grew to rely on it... it runs the whole damned company! And, we don't have just the 4 GIG of data you spoke of... we have 55 GIG!

There is a bit of hope, though. My 2 DBA's and I sat down and hammered out a plan that worked. While you should NOT use this "work around" as an excuse to continue to do things the wrong way, it does work when no other possibility exists.

Just to restate your problem... you have this miserable "Counter" table that your procs rely on. The proc that drives the Counter table is relegated to 100% RBAR (pronounced "ree-bar" and is a "Modenism" for "Row By Agonizing Row"). You goal is to enable it to allow for more than one row without having to rewrite every bloody stored procedure that currently uses it in that fashion...

... my goal is to help you do that and to do it in a manner that will virtually eliminate the deadlocks that I think the current proc is causing. Hopefully, your DBA has "TRACE FLAG 1204" enabled and is monitoring the SQL Server log for deadlocks. If not, you must get the DBA to start doing that immediately!

Ok... here we go... by the numbers...

STEP 1 - Have the DBA turn on "TRACE FLAG 1204" and start monitoring the SQL Server Log for deadlocks. I repeat this because it is so very important. The DBA should provide you and other concerned parties with a daily count of not only how many deadlocks there are, but what caused them. It's a job a DBA should be doing, anyway.

STEP 2 - Rewrite the GetNextBookNumber Proc as follows...

 CREATE PROCEDURE dbo.GetNextBookNumber
/******************************************************************************
Purpose:
This store procedure is used to get the "Next Book Number" from the Counter
table for any given type that exists and will create a new type if it doesn't
already exist.

If only the CounterType is provided, the Increment will default to "1" which
will allow other procs currently calling this proc to continue to do so
without change.

If an "Increment" is provided, the CounterValue for the matching CounterType
will be incrementd by that amount.

In either case, @NextBookNumber will return a single value which will be the
desired CounterValue and the next increment of values will be "reserved".

WARNING: NEVER USE THIS PROC IN A DECLARED TRANSACTION. THE RESULTS OF THIS
PROC MUST NEVER BE ALLOWED TO ROLLBACK OR DUPLICATE COUNTER VALUES
MAY RESULT ALONG WITH A WAD OF DEADLOCKS TO BOOT!

Example Usages:
1. For currently existing procs... do as before (whatever that was)

2. For new and rewritten procs that will use 1 or more values

EXEC dbo.GetNextBookNumber countertype, increment, @NextBookNumber OUT

@NextBookNumber (must be previously declared) will contain the lowest
counter value in the requested "increment" of numbers.

Revision History:
Rev 00 - 12/31/2006 - Jeff Moden - Initial creation
******************************************************************************/
--===== Declare parameters
@CounterType VARCHAR(10),
@Increment = 1 FLOAT,
@NextBookNumber FLOAT OUTPUT
AS
SET NOCOUNT ON

--===== If the CounterType does not already exist, create a new entry
-- for it in the counter table (I think this is very dangerous and it
-- should be removed)
IF NOT EXISTS (SELECT 1 FROM Counter WHERE CounterType = @CounterType)
INSERT INTO dbo.Counter (CounterType) VALUES (@CounterType)

--===== Update the CounterValue and get the return all at the same time so
-- we don't need a transaction that will certainly cause deadlocks on
-- this "hotspot" table.
UPDATE dbo.Counter
SET @NextBookNumber = CounterValue = ISNULL(CounterValue,1) + @Increment
WHERE @CounterType = @CounterType

--===== Subtract the increment from the number we just updated to get the
-- actual next available CounterValue
SET @NextBookNumber = @NextBookNumber - @Increment

RETURN


STEP 3 - Use the new proc for currently written procs. No need to change the existing procs (although, you should because they had to be written using RBAR). Just call the new proc the same way you have been (so, no changes, really, 'cause the name of the new proc is the same as the old one). HOWEVER, YOU MUST NOT CALL THIS PROC (or the old one, for that matter) WITHIN A TRANSACTION NOR MUST YOU EVER ALLOW A ROLLBACK ON THIS CODE.

STEP 4 - Use the new proc for new procedures...
Like I said, you really need to fix things so that you don't need to use the Counter table. That, not-with-standing, here's how to use it...

4.0 Declare @Increment and @NextBookNumber as a FLOAT (as I said previously, not my first choice in data-types)

4.1 Create a #Temp table that DOES have an IDENTITY(1,1) column called "RowNum" and whatever columns you may wish to add, as well. You kinda did this before but were missing the identity column. Fill the #Temp table with whatever you need to fill it with. DO NOT DELETE FROM THIS TABLE! Make sure you only put known good data in this table.

4.2 Figure out how many rows you put in the #Temp table. If there is at least one row in the table, you can easily and quickly do that with SELECT @Increment = IDENT_CURRENT('#Temp')

4.3 Call your new GetNextBookNumber proc using (let's say you need this for the "BookCode" counter type...
EXEC dbo.GetNextBookNumber 'BookCode', @Increment, @NextBookNumber OUT


4.4 Insert the new data into the target table... the "-1" is absolutely essential...

INSERT INTO sometable
(Bookcode, othercolumn, othercolumn, othercolumn, etc...)
SELECT RowNum + @NextBookNumber - 1 AS Bookcode,
... other column AS column ...
... other column AS column ...
... other column AS column ...
... etc...
FROM #Temp

All done... That's your "work around" and it's fairly effective for such a bad way to do things.

You should still concentrate on fixing the design of the database so you don't need such trickery to get the job done. And, make sure you document your code so YOU can figure it out a year from now when you need to fix it




--Jeff Moden
Go to Top of Page

kamii47
Constraint Violating Yak Guru

353 Posts

Posted - 2007-01-03 : 01:15:03
Thanks jeff.
I have to empty the temp table.
Go to Top of Page
    Next Page

- Advertisement -