Я подготовил пример ниже.Я не могу заполнить таблицу @ids
внутри хранимой процедуры deleteByMonth
, хотя запрос дает результат.Я думаю, что это проблема, связанная с переменной областью действия @ids
или из-за неправильного использования операторов потока управления.Насколько я понимаю, @ids
должен быть доступен в рамках хранимой процедуры.Когда я удаляю IF...ELSE
и BEGIN...END
и BEGIN TRANSACTION...COMMIT TRANSACTION
соответственно (что я не хочу), заполняется @ids
и выполняется оператор delete
.Почему я не могу вставить в свою @ids
табличную переменную?
create database test03;
go
use test03;
go
create table TestEntity (
testId bigint not null,
dateT datetime not null,
inGroup int not null,
done bit not null,
primary key(testId,dateT)
)
insert into TestEntity (testId, dateT, inGroup, done)
values(99999,'2018-10-05',2,1)
insert into TestEntity (testId, dateT,inGroup, done)
values(99999,'2018-09-01',2,1)
insert into TestEntity (testId, dateT,inGroup, done)
values(77777,'2018-10-04',7,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(77777,'2018-08-01',7,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(88888,'2018-10-05',2,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(88888,'2018-09-01',2,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(88888,'2018-10-04',2,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(88888,'2018-08-01',2,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(3333,'2018-08-01',8,0)
insert into TestEntity (testId, dateT,inGroup, done)
values(3333,'2018-10-01',8,0)
go
create function isDone (@id bigint)
returns bit
as
begin
declare @r int;
declare @d int;
select @r=sum(@@ROWCOUNT), @d=sum(cast(done as int)) from TestEntity
where testId = @id and done = 1
return IIF(@r=@d,1,0)
end
go
CREATE procedure [dbo].[deleteByMonth]
(
@month int
)
as
DECLARE @ids TABLE (t bigint not null)
BEGIN
IF (@month is null or @month = 0)
BEGIN
RAISERROR('invalid month parameter!',11,1) RETURN;
END
ELSE
BEGIN
BEGIN TRANSACTION
insert into @ids
select TestEntity.testId
from TestEntity
where
(TestEntity.inGroup = 2 and dbo.isDone(TestEntity.testId) = 1)
group by
TestEntity.testId
having
(month(max(dateT)) <= @month)
delete from TestEntity where TestEntity.testId in (select t from @ids)
COMMIT TRANSACTION
END
END
select * from TestEntity
exec deleteByMonth 10
Поскольку проблема была @@ROWCOUNT
, я адаптировал функцию следующим образом.Моя цель - сравнить фактическое количество строк с количеством флагов, установленных для testId
ALTER FUNCTION [dbo].[isDone](@id BIGINT)
RETURNS BIT
AS
BEGIN
DECLARE @r INT;
DECLARE @d INT;
select @r = r, @d= SUM(CAST(done AS INT)) from TestEntity ti
inner join (
select COUNT(*) as r, testId from TestEntity
group by testId) as ton on
ti.testId = ton.testId
where ton.testId = @id group by ton.r
RETURN IIF(@r = @d, 1, 0);
END;