[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.sqlserver.programming

Delete with cursor not working

Jeff Reese

3/28/2007 3:36:00 PM

Hello.

I'm using SQL Server 2005.

What I'm trying to accomplish: Using a cursor to move through records and do
some data cleanup to remove duplicates

An example:
Record_ID Category
1 Created
1 Deleted
1 Deleted

In this example, I need to delete the second 'Deleted' row.

The problem: I'm using the delete from <table> where current of cursor and
it's not working. Does anyone see the problem with this code? I essentially
use variables to collect values of current and prior rows and compare them to
see if they're a match. No errors are returned, but my duplicates are still
there...

Any help is appreciated.


declare
@v_prior_record_id char(10)
, @v_prior_change_type varchar(20)
, @v_current_record_id char(10)
, @v_current_change_type varchar(20)

declare c_cleanup cursor for
select mt.record_id
, mt.change_type
from my_table mt
order by record_id, change_date

open c_cleanup
while @@fetch_status = 0
begin
fetch next from c_cleanup into @v_current_record_id, @v_current_change_type

if @v_current_record_id = @v_prior_record_id
and @v_current_change_type = @v_prior_change_type
delete from my_table
where current of c_cleanup

set @v_prior_record_id = @v_current_record_id
set @v_prior_change_type = @v_current_change_type

end



--
Jeff
11 Answers

Alejandro Mesa

3/28/2007 3:56:00 PM

0

Jeff Reese,

The sample data is not in synch with the "select" statement you are using to
declare the cursor. I do not see column [change_date] in the sample data and
neither column [Category] when declaring the cursor. Can you explain what you
are trying to do (be more explicit)?

See if this helps:

;with cte
as
(
select
record_id, change_date, change_type,
row_number() over(partition by record_id, change_type order by
change_date) as rn
from
my_table
)
delete cte
where rn > 1;

Code has not been tested.

AMB


"Jeff Reese" wrote:

> Hello.
>
> I'm using SQL Server 2005.
>
> What I'm trying to accomplish: Using a cursor to move through records and do
> some data cleanup to remove duplicates
>
> An example:
> Record_ID Category
> 1 Created
> 1 Deleted
> 1 Deleted
>
> In this example, I need to delete the second 'Deleted' row.
>
> The problem: I'm using the delete from <table> where current of cursor and
> it's not working. Does anyone see the problem with this code? I essentially
> use variables to collect values of current and prior rows and compare them to
> see if they're a match. No errors are returned, but my duplicates are still
> there...
>
> Any help is appreciated.
>
>
> declare
> @v_prior_record_id char(10)
> , @v_prior_change_type varchar(20)
> , @v_current_record_id char(10)
> , @v_current_change_type varchar(20)
>
> declare c_cleanup cursor for
> select mt.record_id
> , mt.change_type
> from my_table mt
> order by record_id, change_date
>
> open c_cleanup
> while @@fetch_status = 0
> begin
> fetch next from c_cleanup into @v_current_record_id, @v_current_change_type
>
> if @v_current_record_id = @v_prior_record_id
> and @v_current_change_type = @v_prior_change_type
> delete from my_table
> where current of c_cleanup
>
> set @v_prior_record_id = @v_current_record_id
> set @v_prior_change_type = @v_current_change_type
>
> end
>
>
>
> --
> Jeff

Jeff Reese

3/28/2007 4:08:00 PM

0

Alejandro,

Yes, I definitely have some typos. Let me correct. Here's a more realistic
set of data:

Record_ID Change_Type Change_Date
1 Created 3/1/07
1 Resolved 3/1/07
1 Resolved 3/2/07
1 Reopened 3/3/07
1 Resolved 3/4/07
1 Resolved 3/5/07

In this scenario... I want to delete Resolved on 3/2 and Resolved on 3/5.
The others are valid.

Thanks.


--
Jeff


"Alejandro Mesa" wrote:

> Jeff Reese,
>
> The sample data is not in synch with the "select" statement you are using to
> declare the cursor. I do not see column [change_date] in the sample data and
> neither column [Category] when declaring the cursor. Can you explain what you
> are trying to do (be more explicit)?
>
> See if this helps:
>
> ;with cte
> as
> (
> select
> record_id, change_date, change_type,
> row_number() over(partition by record_id, change_type order by
> change_date) as rn
> from
> my_table
> )
> delete cte
> where rn > 1;
>
> Code has not been tested.
>
> AMB
>
>
> "Jeff Reese" wrote:
>
> > Hello.
> >
> > I'm using SQL Server 2005.
> >
> > What I'm trying to accomplish: Using a cursor to move through records and do
> > some data cleanup to remove duplicates
> >
> > An example:
> > Record_ID Category
> > 1 Created
> > 1 Deleted
> > 1 Deleted
> >
> > In this example, I need to delete the second 'Deleted' row.
> >
> > The problem: I'm using the delete from <table> where current of cursor and
> > it's not working. Does anyone see the problem with this code? I essentially
> > use variables to collect values of current and prior rows and compare them to
> > see if they're a match. No errors are returned, but my duplicates are still
> > there...
> >
> > Any help is appreciated.
> >
> >
> > declare
> > @v_prior_record_id char(10)
> > , @v_prior_change_type varchar(20)
> > , @v_current_record_id char(10)
> > , @v_current_change_type varchar(20)
> >
> > declare c_cleanup cursor for
> > select mt.record_id
> > , mt.change_type
> > from my_table mt
> > order by record_id, change_date
> >
> > open c_cleanup
> > while @@fetch_status = 0
> > begin
> > fetch next from c_cleanup into @v_current_record_id, @v_current_change_type
> >
> > if @v_current_record_id = @v_prior_record_id
> > and @v_current_change_type = @v_prior_change_type
> > delete from my_table
> > where current of c_cleanup
> >
> > set @v_prior_record_id = @v_current_record_id
> > set @v_prior_change_type = @v_current_change_type
> >
> > end
> >
> >
> >
> > --
> > Jeff

Aaron [SQL Server MVP]

3/28/2007 5:18:00 PM

0

You don't need a cursor for this at all. Try this with some sample tables:

DELETE
p
FROM
your_table p
INNER JOIN
your_table x
ON
p.change_type = x.change_type
AND p.record_id = x.record_id
AND p.change_date > x.change_date
-- where p.record_id = 1 AND x.record_id = 1
;

--
Aaron Bertrand
SQL Server MVP
http://www.sq...
http://www.aspfa...







"Jeff Reese" <JeffReese@discussions.microsoft.com> wrote in message
news:D524128D-FB53-4C70-BFED-05B9B7B58A18@microsoft.com...
> Alejandro,
>
> Yes, I definitely have some typos. Let me correct. Here's a more
> realistic
> set of data:
>
> Record_ID Change_Type Change_Date
> 1 Created 3/1/07
> 1 Resolved 3/1/07
> 1 Resolved 3/2/07
> 1 Reopened 3/3/07
> 1 Resolved 3/4/07
> 1 Resolved 3/5/07
>
> In this scenario... I want to delete Resolved on 3/2 and Resolved on
> 3/5.
> The others are valid.
>
> Thanks.
>
>
> --
> Jeff
>
>
> "Alejandro Mesa" wrote:
>
>> Jeff Reese,
>>
>> The sample data is not in synch with the "select" statement you are using
>> to
>> declare the cursor. I do not see column [change_date] in the sample data
>> and
>> neither column [Category] when declaring the cursor. Can you explain what
>> you
>> are trying to do (be more explicit)?
>>
>> See if this helps:
>>
>> ;with cte
>> as
>> (
>> select
>> record_id, change_date, change_type,
>> row_number() over(partition by record_id, change_type order by
>> change_date) as rn
>> from
>> my_table
>> )
>> delete cte
>> where rn > 1;
>>
>> Code has not been tested.
>>
>> AMB
>>
>>
>> "Jeff Reese" wrote:
>>
>> > Hello.
>> >
>> > I'm using SQL Server 2005.
>> >
>> > What I'm trying to accomplish: Using a cursor to move through records
>> > and do
>> > some data cleanup to remove duplicates
>> >
>> > An example:
>> > Record_ID Category
>> > 1 Created
>> > 1 Deleted
>> > 1 Deleted
>> >
>> > In this example, I need to delete the second 'Deleted' row.
>> >
>> > The problem: I'm using the delete from <table> where current of cursor
>> > and
>> > it's not working. Does anyone see the problem with this code? I
>> > essentially
>> > use variables to collect values of current and prior rows and compare
>> > them to
>> > see if they're a match. No errors are returned, but my duplicates are
>> > still
>> > there...
>> >
>> > Any help is appreciated.
>> >
>> >
>> > declare
>> > @v_prior_record_id char(10)
>> > , @v_prior_change_type varchar(20)
>> > , @v_current_record_id char(10)
>> > , @v_current_change_type varchar(20)
>> >
>> > declare c_cleanup cursor for
>> > select mt.record_id
>> > , mt.change_type
>> > from my_table mt
>> > order by record_id, change_date
>> >
>> > open c_cleanup
>> > while @@fetch_status = 0
>> > begin
>> > fetch next from c_cleanup into @v_current_record_id,
>> > @v_current_change_type
>> >
>> > if @v_current_record_id = @v_prior_record_id
>> > and @v_current_change_type = @v_prior_change_type
>> > delete from my_table
>> > where current of c_cleanup
>> >
>> > set @v_prior_record_id = @v_current_record_id
>> > set @v_prior_change_type = @v_current_change_type
>> >
>> > end
>> >
>> >
>> >
>> > --
>> > Jeff


Aaron [SQL Server MVP]

3/28/2007 5:19:00 PM

0

Sorry, my suggestion was not accurate, and would actually delete three rows
instead of 2.

Let me try again in a few minutes.

--
Aaron Bertrand
SQL Server MVP
http://www.sq...
http://www.aspfa...



Alejandro Mesa

3/28/2007 5:24:00 PM

0

Jeff Reese,

See if this helps.

create table dbo.t1 (
record_id int not null,
change_type varchar(25) not null,
change_date datetime
)
go

insert into dbo.t1 values(1, 'Created', '3/1/07')
insert into dbo.t1 values(1, 'Resolved', '3/1/07')
insert into dbo.t1 values(1, 'Resolved', '3/2/07')
insert into dbo.t1 values(1, 'Reopened', '3/3/07')
insert into dbo.t1 values(1, 'Resolved', '3/4/07')
insert into dbo.t1 values(1, 'Resolved', '3/5/07')
go

;with cte
as
(
select
record_id, change_date, change_type,
row_number() over(partition by record_id order by change_date) as rn
from
dbo.t1
)
delete
b
from
cte as a
inner join
cte as b
on a.record_id = b.record_id
and a.change_type = b.change_type
and a.rn = b.rn - 1
go

select *
from dbo.t1
order by record_id, change_date
go

drop table dbo.t1
go


AMB

"Jeff Reese" wrote:

> Alejandro,
>
> Yes, I definitely have some typos. Let me correct. Here's a more realistic
> set of data:
>
> Record_ID Change_Type Change_Date
> 1 Created 3/1/07
> 1 Resolved 3/1/07
> 1 Resolved 3/2/07
> 1 Reopened 3/3/07
> 1 Resolved 3/4/07
> 1 Resolved 3/5/07
>
> In this scenario... I want to delete Resolved on 3/2 and Resolved on 3/5.
> The others are valid.
>
> Thanks.
>
>
> --
> Jeff
>
>
> "Alejandro Mesa" wrote:
>
> > Jeff Reese,
> >
> > The sample data is not in synch with the "select" statement you are using to
> > declare the cursor. I do not see column [change_date] in the sample data and
> > neither column [Category] when declaring the cursor. Can you explain what you
> > are trying to do (be more explicit)?
> >
> > See if this helps:
> >
> > ;with cte
> > as
> > (
> > select
> > record_id, change_date, change_type,
> > row_number() over(partition by record_id, change_type order by
> > change_date) as rn
> > from
> > my_table
> > )
> > delete cte
> > where rn > 1;
> >
> > Code has not been tested.
> >
> > AMB
> >
> >
> > "Jeff Reese" wrote:
> >
> > > Hello.
> > >
> > > I'm using SQL Server 2005.
> > >
> > > What I'm trying to accomplish: Using a cursor to move through records and do
> > > some data cleanup to remove duplicates
> > >
> > > An example:
> > > Record_ID Category
> > > 1 Created
> > > 1 Deleted
> > > 1 Deleted
> > >
> > > In this example, I need to delete the second 'Deleted' row.
> > >
> > > The problem: I'm using the delete from <table> where current of cursor and
> > > it's not working. Does anyone see the problem with this code? I essentially
> > > use variables to collect values of current and prior rows and compare them to
> > > see if they're a match. No errors are returned, but my duplicates are still
> > > there...
> > >
> > > Any help is appreciated.
> > >
> > >
> > > declare
> > > @v_prior_record_id char(10)
> > > , @v_prior_change_type varchar(20)
> > > , @v_current_record_id char(10)
> > > , @v_current_change_type varchar(20)
> > >
> > > declare c_cleanup cursor for
> > > select mt.record_id
> > > , mt.change_type
> > > from my_table mt
> > > order by record_id, change_date
> > >
> > > open c_cleanup
> > > while @@fetch_status = 0
> > > begin
> > > fetch next from c_cleanup into @v_current_record_id, @v_current_change_type
> > >
> > > if @v_current_record_id = @v_prior_record_id
> > > and @v_current_change_type = @v_prior_change_type
> > > delete from my_table
> > > where current of c_cleanup
> > >
> > > set @v_prior_record_id = @v_current_record_id
> > > set @v_prior_change_type = @v_current_change_type
> > >
> > > end
> > >
> > >
> > >
> > > --
> > > Jeff

Aaron [SQL Server MVP]

3/28/2007 5:28:00 PM

0

Thanks for the save. I was trying a non-2005 approach because I missed that
in the original message.




"Alejandro Mesa" <AlejandroMesa@discussions.microsoft.com> wrote in message
news:7DC9BBDE-6661-4117-8C50-D604728284C7@microsoft.com...
> Jeff Reese,
>
> See if this helps.
>
> create table dbo.t1 (
> record_id int not null,
> change_type varchar(25) not null,
> change_date datetime
> )
> go
>
> insert into dbo.t1 values(1, 'Created', '3/1/07')
> insert into dbo.t1 values(1, 'Resolved', '3/1/07')
> insert into dbo.t1 values(1, 'Resolved', '3/2/07')
> insert into dbo.t1 values(1, 'Reopened', '3/3/07')
> insert into dbo.t1 values(1, 'Resolved', '3/4/07')
> insert into dbo.t1 values(1, 'Resolved', '3/5/07')
> go
>
> ;with cte
> as
> (
> select
> record_id, change_date, change_type,
> row_number() over(partition by record_id order by change_date) as rn
> from
> dbo.t1
> )
> delete
> b
> from
> cte as a
> inner join
> cte as b
> on a.record_id = b.record_id
> and a.change_type = b.change_type
> and a.rn = b.rn - 1
> go
>
> select *
> from dbo.t1
> order by record_id, change_date
> go
>
> drop table dbo.t1
> go
>
>
> AMB


Jeff Reese

3/28/2007 5:44:00 PM

0

Alejandro,

Thanks. I'm getting the following errors:

Msg 170, Level 15, State 1, Line 2
Line 2: Incorrect syntax near ';'.
Msg 195, Level 15, State 10, Line 7
'row_number' is not a recognized function name.

--
Jeff


"Alejandro Mesa" wrote:

> Jeff Reese,
>
> See if this helps.
>
> create table dbo.t1 (
> record_id int not null,
> change_type varchar(25) not null,
> change_date datetime
> )
> go
>
> insert into dbo.t1 values(1, 'Created', '3/1/07')
> insert into dbo.t1 values(1, 'Resolved', '3/1/07')
> insert into dbo.t1 values(1, 'Resolved', '3/2/07')
> insert into dbo.t1 values(1, 'Reopened', '3/3/07')
> insert into dbo.t1 values(1, 'Resolved', '3/4/07')
> insert into dbo.t1 values(1, 'Resolved', '3/5/07')
> go
>
> ;with cte
> as
> (
> select
> record_id, change_date, change_type,
> row_number() over(partition by record_id order by change_date) as rn
> from
> dbo.t1
> )
> delete
> b
> from
> cte as a
> inner join
> cte as b
> on a.record_id = b.record_id
> and a.change_type = b.change_type
> and a.rn = b.rn - 1
> go
>
> select *
> from dbo.t1
> order by record_id, change_date
> go
>
> drop table dbo.t1
> go
>
>
> AMB
>
> "Jeff Reese" wrote:
>
> > Alejandro,
> >
> > Yes, I definitely have some typos. Let me correct. Here's a more realistic
> > set of data:
> >
> > Record_ID Change_Type Change_Date
> > 1 Created 3/1/07
> > 1 Resolved 3/1/07
> > 1 Resolved 3/2/07
> > 1 Reopened 3/3/07
> > 1 Resolved 3/4/07
> > 1 Resolved 3/5/07
> >
> > In this scenario... I want to delete Resolved on 3/2 and Resolved on 3/5.
> > The others are valid.
> >
> > Thanks.
> >
> >
> > --
> > Jeff
> >
> >
> > "Alejandro Mesa" wrote:
> >
> > > Jeff Reese,
> > >
> > > The sample data is not in synch with the "select" statement you are using to
> > > declare the cursor. I do not see column [change_date] in the sample data and
> > > neither column [Category] when declaring the cursor. Can you explain what you
> > > are trying to do (be more explicit)?
> > >
> > > See if this helps:
> > >
> > > ;with cte
> > > as
> > > (
> > > select
> > > record_id, change_date, change_type,
> > > row_number() over(partition by record_id, change_type order by
> > > change_date) as rn
> > > from
> > > my_table
> > > )
> > > delete cte
> > > where rn > 1;
> > >
> > > Code has not been tested.
> > >
> > > AMB
> > >
> > >
> > > "Jeff Reese" wrote:
> > >
> > > > Hello.
> > > >
> > > > I'm using SQL Server 2005.
> > > >
> > > > What I'm trying to accomplish: Using a cursor to move through records and do
> > > > some data cleanup to remove duplicates
> > > >
> > > > An example:
> > > > Record_ID Category
> > > > 1 Created
> > > > 1 Deleted
> > > > 1 Deleted
> > > >
> > > > In this example, I need to delete the second 'Deleted' row.
> > > >
> > > > The problem: I'm using the delete from <table> where current of cursor and
> > > > it's not working. Does anyone see the problem with this code? I essentially
> > > > use variables to collect values of current and prior rows and compare them to
> > > > see if they're a match. No errors are returned, but my duplicates are still
> > > > there...
> > > >
> > > > Any help is appreciated.
> > > >
> > > >
> > > > declare
> > > > @v_prior_record_id char(10)
> > > > , @v_prior_change_type varchar(20)
> > > > , @v_current_record_id char(10)
> > > > , @v_current_change_type varchar(20)
> > > >
> > > > declare c_cleanup cursor for
> > > > select mt.record_id
> > > > , mt.change_type
> > > > from my_table mt
> > > > order by record_id, change_date
> > > >
> > > > open c_cleanup
> > > > while @@fetch_status = 0
> > > > begin
> > > > fetch next from c_cleanup into @v_current_record_id, @v_current_change_type
> > > >
> > > > if @v_current_record_id = @v_prior_record_id
> > > > and @v_current_change_type = @v_prior_change_type
> > > > delete from my_table
> > > > where current of c_cleanup
> > > >
> > > > set @v_prior_record_id = @v_current_record_id
> > > > set @v_prior_change_type = @v_current_change_type
> > > >
> > > > end
> > > >
> > > >
> > > >
> > > > --
> > > > Jeff

Aaron [SQL Server MVP]

3/28/2007 5:53:00 PM

0

You said you were using SQL 2005, right? Is it possible you are in 80
compatibility mode?

--
Aaron Bertrand
SQL Server MVP
http://www.sq...
http://www.aspfa...




"Jeff Reese" <JeffReese@discussions.microsoft.com> wrote in message
news:67D4C3BF-64E6-49AF-B428-87E663C43806@microsoft.com...
> Alejandro,
>
> Thanks. I'm getting the following errors:
>
> Msg 170, Level 15, State 1, Line 2
> Line 2: Incorrect syntax near ';'.
> Msg 195, Level 15, State 10, Line 7
> 'row_number' is not a recognized function name.


Alejandro Mesa

3/28/2007 5:56:00 PM

0

Hi Aaron,

You are welcome.

Regards,

Alejendro Mesa


"Aaron Bertrand [SQL Server MVP]" wrote:

> Thanks for the save. I was trying a non-2005 approach because I missed that
> in the original message.
>
>
>
>
> "Alejandro Mesa" <AlejandroMesa@discussions.microsoft.com> wrote in message
> news:7DC9BBDE-6661-4117-8C50-D604728284C7@microsoft.com...
> > Jeff Reese,
> >
> > See if this helps.
> >
> > create table dbo.t1 (
> > record_id int not null,
> > change_type varchar(25) not null,
> > change_date datetime
> > )
> > go
> >
> > insert into dbo.t1 values(1, 'Created', '3/1/07')
> > insert into dbo.t1 values(1, 'Resolved', '3/1/07')
> > insert into dbo.t1 values(1, 'Resolved', '3/2/07')
> > insert into dbo.t1 values(1, 'Reopened', '3/3/07')
> > insert into dbo.t1 values(1, 'Resolved', '3/4/07')
> > insert into dbo.t1 values(1, 'Resolved', '3/5/07')
> > go
> >
> > ;with cte
> > as
> > (
> > select
> > record_id, change_date, change_type,
> > row_number() over(partition by record_id order by change_date) as rn
> > from
> > dbo.t1
> > )
> > delete
> > b
> > from
> > cte as a
> > inner join
> > cte as b
> > on a.record_id = b.record_id
> > and a.change_type = b.change_type
> > and a.rn = b.rn - 1
> > go
> >
> > select *
> > from dbo.t1
> > order by record_id, change_date
> > go
> >
> > drop table dbo.t1
> > go
> >
> >
> > AMB
>
>
>

Jeff Reese

3/28/2007 8:40:00 PM

0

Aaron and Alejandro,

I apologize. I realized that while I'm running 2005 on my machine the
server I'm querying is using 2000...

I also figured out the problem with my cursor - the order of my statements
was causing the problem...

I really appreciate your suggestions today - sorry for the miscommunication.

--
Jeff


"Aaron Bertrand [SQL Server MVP]" wrote:

> You said you were using SQL 2005, right? Is it possible you are in 80
> compatibility mode?
>
> --
> Aaron Bertrand
> SQL Server MVP
> http://www.sq...
> http://www.aspfa...
>
>
>
>
> "Jeff Reese" <JeffReese@discussions.microsoft.com> wrote in message
> news:67D4C3BF-64E6-49AF-B428-87E663C43806@microsoft.com...
> > Alejandro,
> >
> > Thanks. I'm getting the following errors:
> >
> > Msg 170, Level 15, State 1, Line 2
> > Line 2: Incorrect syntax near ';'.
> > Msg 195, Level 15, State 10, Line 7
> > 'row_number' is not a recognized function name.
>
>
>