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 intset @counter = scope_identity()Read books online |
 |
|
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 wayI don't think so it will be autoIncremented in my queryI 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. |
 |
|
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=2644Chiraghttp://chirikworld.blogspot.com/ |
 |
|
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 TestBookTableTempwhere SourceId = @SourceIdand BookCode not in(select BookCodefrom TestBookTablewhere SourceId = @SourceId ) |
 |
|
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?Chiraghttp://chirikworld.blogspot.com/ |
 |
|
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 |
 |
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2006-12-26 : 03:02:03
|
http://sqlteam.com/forums/topic.asp?TOPIC_ID=76821MadhivananFailing to plan is Planning to fail |
 |
|
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))ASBegin 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 = @CounterValueEndGO--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 @CounterValueEnd --Your Insert StatementInsert into TestJobTable (BookNumber,BookCode,IsActive,SourceId,ContactNumber)select Dbo.GETNextBookNum('Book'),BookCode,'1', @SourceId ,Dbo.GETNextBookNum('contact') from TestBookTableTempwhere SourceId = @SourceIdand BookCode not in ( select BookCode from TestBookTable where SourceId = @SourceId ) Chiraghttp://chirikworld.blogspot.com/ |
 |
|
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 tableChiraghttp://chirikworld.blogspot.com/ |
 |
|
afrika
Master Smack Fu Yak Hacker
2706 Posts |
Posted - 2006-12-26 : 05:23:03
|
Chirag, its xmas !!! Remember Take a break. Brilliant work |
 |
|
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...Chiraghttp://chirikworld.blogspot.com/ |
 |
|
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 |
 |
|
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 |
 |
|
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. |
 |
|
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 ? |
 |
|
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. |
 |
|
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 ? |
 |
|
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. |
 |
|
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 |
 |
|
kamii47
Constraint Violating Yak Guru
353 Posts |
Posted - 2007-01-03 : 01:15:03
|
Thanks jeff.I have to empty the temp table. |
 |
|
Next Page
|