December 8, 2011 at 12:18 pm
Hi,
I'm new to cursor. I want to compare the b_date and e_date of two records having same emp_num.
DECLARE @emp_num VARCHAR(30)
DECLARE @begin_date DATETIME
DECLARE @end_date DATETIME
DECLARE cur CURSOR
SELECT emp_num, b_date, e_date FROM sysGen ORDER BY emp_num,b_date
OPEN cur
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF( compare two consecutive records : if the first records b_date is greater than second records e_date)
Please assist me here.
Thanks in advance!
December 8, 2011 at 12:27 pm
ashisht4u (12/8/2011)
I'm new to cursor. I want to compare the b_date and e_date of two records having same emp_num.DECLARE @emp_num VARCHAR(30)
DECLARE @begin_date DATETIME
DECLARE @end_date DATETIME
DECLARE cur CURSOR
SELECT emp_num, b_date, e_date FROM sysGen ORDER BY emp_num,b_date
OPEN cur
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF( compare two consecutive records : if the first records b_date is greater than second records e_date)
Please assist me here.
You can define the cursor as SCROLL, do two NEXT reads into different variables, do whatever you have to do then do a PRIOR to move back one step on your cursor and start again with the two NEXTs.
_____________________________________
Pablo (Paul) Berzukov
Author of Understanding Database Administration available at Amazon and other bookstores.
Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.December 8, 2011 at 12:33 pm
could you please give me an example of this?
December 8, 2011 at 12:34 pm
NOw, how about explaining what it is you are trying to accomplish? Also, it may also help if you provided us with the DDL (CREATE TABLE statement) for the table, some sample data (i.e. not production data) as a series of insert into statements, and what your expected results are based on that sample data.
Depending on what you are trying to accomplish, using cursors may not even be necessary.
December 8, 2011 at 12:42 pm
Lynn Pettis (12/8/2011)
Depending on what you are trying to accomplish, using cursors may not even be necessary.
I'm pretty sure this is homework, that's why I'm just pointing poster's nose in the right direction and letting him/her do the leg work
_____________________________________
Pablo (Paul) Berzukov
Author of Understanding Database Administration available at Amazon and other bookstores.
Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.December 8, 2011 at 12:56 pm
PaulB-TheOneAndOnly (12/8/2011)
Lynn Pettis (12/8/2011)
Depending on what you are trying to accomplish, using cursors may not even be necessary.I'm pretty sure this is homework, that's why I'm just pointing poster's nose in the right direction and letting him/her do the leg work
Probably right, but still would be nice to know more about what the OP is trying to accomplish.
December 9, 2011 at 2:51 am
Thanks for your expertise.
Its working now.
December 12, 2011 at 11:33 am
I'm facing the out of memory error on executing the cursor query.
Then I modified my query, I thought using two cursor may get rid of 'out of memory' but the following doesn't work.
DECLARE @emp_num VARCHAR(30)
DECLARE @begin_date DATETIME
DECLARE @end_date DATETIME
DECLARE @emp_num1 VARCHAR(30)
DECLARE @begin_date1 DATETIME
DECLARE @end_date1 DATETIME
DECLARE @outerEmp VARCHAR(30)
DECLARE outerCur CURSOR FOR
SELECT DISTINCT(emp_num) FROM sysGen WHERE broker=@broker ORDER BY emp_num
open outerCur
fetch next from outerCur into
@outerEmp
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE cur CURSOR
SELECT emp_num, b_date, e_date FROM sysGen where emp_num=@outerEmp ORDER BY b_date
OPEN cur
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
FETCH NEXT FROM cur INTO
@emp_num1
@begin_date1
@end_date1
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@emp_num = @emp_num1 )
BEGIN
IF ISDATE(@end_date) =0
BEGIN
FETCH PRIOR FROM cur
set end_date = @begin_date1 - 1
WHERE CURRENT OF cur
FETCH NEXT FROM cur
END
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
FETCH NEXT FROM cur INTO
@emp_num1
@begin_date1
@end_date1
END
close cur
deallocate cur
FETCH NEXT FROM outerCur INTO
@outerEmp
END
CLOSE outerCur
DEALLOCATE outerCur
December 12, 2011 at 11:42 am
I have to ask again, what are you trying to accomplish besides learning how to use cursors?
December 12, 2011 at 11:44 am
This really should be done without a cursor. From what I see in the logic there just is not a need for a cursor at all.
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
December 12, 2011 at 1:13 pm
Lynn,
Actually I'm preparing for my interview and I came across some of the question on DB, I'm at C++ but not done much work on SQL-Server. I want to learn db scripting.
Sean,
Can you provide some more information on how could I implement this without using cursor.
Your help on this is appreciated.
December 12, 2011 at 1:31 pm
First, since you are preparing for an interview, the best advice I can give is stay away from cursors. There is almost always a set-based solution to solving problems where developers have used cursors.
Second, looking at the code you have so far, I have no idea what you are attempting to accomplish. You haven't provided us with the DDL (CREATE TABLE scripts) for the table(s) involved, no sample data (as a series of INSERT INTO statements) to populate the table(s), nor the expected results based on the sample data.
December 12, 2011 at 1:33 pm
ashisht4u (12/12/2011)
Lynn,Actually I'm preparing for my interview and I came across some of the question on DB, I'm at C++ but not done much work on SQL-Server. I want to learn db scripting.
Sean,
Can you provide some more information on how could I implement this without using cursor.
Your help on this is appreciated.
This isn't something you can cram on for an interview. There is no hard and fast set of rules that would do this. This is a change in how you think about data. Think about what you want to do to the column instead of each row. Cursors manipulate data row by agonizing row. They slow and inefficient.
Especially since you are new to sql server do yourself a favor and forget you ever heard about their existence. In the case of your example you wanted to update a row with the most recent row prior to this one (based on a certain column) IF the current row did not have a date set. In C++ you would loop through them and back up one if you needed that value. In sql we do the whole operation in a single update statement to avoid looping. Could this be done in a cursor, absolutely. Will the performance suffer in a table after it hits 10,000 rows, absolutely. Will you want to shoot yourself because this takes 20-30 minutes when the rowcount gets up around 500,000, absolutely.
Here are a couple article from this site about cursors and how to get rid of them.
http://www.sqlservercentral.com/articles/T-SQL/66097/%5B/url%5D
and here is an older one too.
http://www.sqlservercentral.com/articles/Advanced+Querying/replacingcursorsandwhileloops/1956/%5B/url%5D
_______________________________________________________________
Need help? Help us help you.
Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.
Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/
December 12, 2011 at 3:12 pm
My bad, sorry I removed few comments and the update statement as well.
Below is the updated query:
DECLARE @emp_num VARCHAR(30)
DECLARE @begin_date DATETIME
DECLARE @end_date DATETIME
DECLARE @emp_num1 VARCHAR(30)
DECLARE @begin_date1 DATETIME
DECLARE @end_date1 DATETIME
DECLARE @outerEmp VARCHAR(30)
DECLARE outerCur CURSOR FOR
SELECT DISTINCT(emp_num) FROM sysGen WHERE broker=@broker ORDER BY emp_num
open outerCur
fetch next from outerCur into
@outerEmp
WHILE (@@FETCH_STATUS = 0)
BEGIN
DECLARE cur CURSOR
SELECT emp_num, b_date, e_date FROM sysGen where emp_num=@outerEmp ORDER BY b_date
OPEN cur
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
FETCH NEXT FROM cur INTO
@emp_num1
@begin_date1
@end_date1
WHILE (@@FETCH_STATUS = 0)
BEGIN
IF (@emp_num = @emp_num1 )
BEGIN
IF ISDATE(@end_date) =0 OR @begin_date1 < @end_date
BEGIN
FETCH PRIOR FROM cur
UPDATE sysGen
SET end_date=@begin_date1 - 1,
WHERE CURRENT OF cur
FETCH NEXT FROM cur
END
FETCH NEXT FROM cur INTO
@emp_num
@begin_date
@end_date
FETCH NEXT FROM cur INTO
@emp_num1
@begin_date1
@end_date1
END
close cur
deallocate cur
FETCH NEXT FROM outerCur INTO
@outerEmp
END
CLOSE outerCur
DEALLOCATE outerCur
ok, so here the objective as given below:
A table has more than 100000+ records, now we need to find out any record where the begin_date is less than the previous record's end date for the same customer. The previous record is the broken one. Also, any previous record with end_date of NULL is also broken.
To achieve this I used cursor as we have to check consicative records.
Sean,
I checked the articals provided, but as we have to trace each and every records and check if that is broken and fix it; I'm not sure how can we replace the cursor with function of something else.
Lynn,
If I leave the cursor concept now then I dont know when I'll get chance to learn it. It makes me feel happy to get usefull information and knowledge from the experts like you and Sean.
December 12, 2011 at 3:58 pm
First, you still haven't provided any of the information I have asked for: CREATE TABLE statement(s), sample data as a series of INSERT INTO statements for the table(s) involved, expected results based on the sample data when done.
Second, 99.9% of the time you don't need cursors to accomplish what you want to do. They are slow and inefficient when compared to set-based solutions.
If you want help, please give us what I have been asking you for in numerous posts.
Viewing 15 posts - 1 through 15 (of 16 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy