Почему я не могу вставить переменную таблицы в хранимую процедуру deleteByMonth, хотя запрос дает результат? - PullRequest
0 голосов
/ 16 октября 2018

Я подготовил пример ниже.Я не могу заполнить таблицу @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;

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Вы можете изменить свою функцию, как показано ниже:

ALTER FUNCTION [dbo].[isDone](@id BIGINT)
RETURNS BIT
AS
     BEGIN
         DECLARE @r INT;
         DECLARE @d INT;
         SELECT @r = SUM(1), 
                @d = SUM(CAST(done AS INT))
         FROM TestEntity
         WHERE testId = @id
               AND done = 1;
         RETURN IIF(@r = @d, 1, 0);
     END;
GO
0 голосов
/ 16 октября 2018

В функции вы используете @@ROWCOUNT, но обычного COUNT(*) будет достаточно.

Измените @r=sum(@@ROWCOUNT) на @r=sum(COUNT(*))

0 голосов
/ 16 октября 2018

Проблема в @@ROWCOUNT в качестве аргумента для передачи dbo.isDone.Когда он передает значение, 0, он получает значение после оператора insert.Значение 0 @@ROWCOUNT определяет критерий, в котором предложение не возвращает значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...