Хранимая процедура, содержащая временную таблицу и курсор, не работает

#sql #sql-server #stored-procedures #temp-tables

#sql #sql-сервер #хранимые процедуры #временные таблицы

Вопрос:

Мне нужно получить иерархию некоторых проектов во временной таблице, потому что проект, для которого создается иерархия, зависит от триггера после обновления. Итак, мне нужно вставить результат хранимой процедуры во временную таблицу. После этого мне нужен курсор, чтобы зациклить все результаты и после этого внести некоторые обновления. Вот мой код..Я не знаю, почему, но она не входит в цикл, или это то, что я думаю.

 ALTER PROCEDURE [dbo].[UPDATE_UDF_VALUES_HIERARCHY] ( 
                @proj_id INT
                                                    ) 
AS
    BEGIN
        DECLARE @tmpHierarchy TABLE ( 
                                    proj_id       INT , 
                                    parent_wbs_id INT
                                    );

        DECLARE @projid INT , @parent_wbs_id INT , @Total INT , @Totaltest INT;
        INSERT INTO @tmpHierarchy ( proj_id , parent_wbs_id
                                  ) 
        EXEC GetHierarchyForProject @proj_id;

        --INSERT INTO @tmpHierarchy
        --Exec GetHierarchyForProject @proj_id
        -- to break the match in all scanora

        UPDATE udfvalue
               SET udf_number = ( SELECT SUM(udf_number)
                                  FROM UDFVALUE
                                  WHERE udf_type_id = 1
                                        AND 
                                        proj_id = @proj_id
                                )
        WHERE udf_type_id = 2
              AND 
              proj_id = @proj_id;

        DECLARE db_cursor_hierarchy_andreea CURSOR

        FOR SELECT *
            FROM @tmpHierarchy;

        OPEN db_cursor_hierarchy_andreea;

        FETCH NEXT FROM db_cursor_hierarchy_andreea INTO @projid , @parent_wbs_id;

        IF @proj_id != @projid
            BEGIN
                IF EXISTS ( SELECT proj_id
                            FROM udfvalue
                            WHERE proj_id = @projid
                                  AND 
                                  udf_type_id = 2
                          ) 
                    BEGIN
                        WHILE @@FETCH_STATUS = 0
                            BEGIN
                                SELECT @Totaltest = SUM(udf_number)
                                FROM udfvalue
                                WHERE udf_type_id = 2
                                      AND 
                                      fk_id IN ( SELECT proj_id
                                                 FROM PROJWBS
                                                 WHERE parent_wbs_id = ( SELECT wbs_id
                                                                         FROM projwbs
                                                                         WHERE proj_id = @projid
                                                                       )
                                               );
                                UPDATE udfvalue
                                       SET udf_number = @Totaltest
                                WHERE udf_type_id = 2
                                      AND 
                                      proj_id = @projid;
                            END;
                    END;
                FETCH NEXT FROM db_cursor_hierarchy_andreea INTO @projid , @parent_wbs_id;

        END;
        CLOSE db_cursor_hierarchy_andreea;
        DEALLOCATE db_cursor_hierarchy_andreea;
    END;
  

Комментарии:

1. Почему вы используете цикл в первую очередь? Вся эта циклическая конструкция и тому подобное могут быть заменены одним оператором update.

2. Что касается отладки вашего текущего кода, добавьте несколько операторов печати во вложенные операторы IF. Я предполагаю, что одно или оба из этих условий являются ложными.

3. результатом ВЫПОЛНЕНИЯ GetHierarchyForProject @proj_id является таблица, которая содержит иерархию для некоторого данного проекта .. и обновление, которое я должен выполнить, влияет на некоторое значение проекта. Возможно, это то, что я упускаю.

4. Кажется, все в порядке?

5. Я бы вообще не использовал здесь никаких операторов if или цикла. Перенесите свои результаты во временную таблицу, а затем выполните однократное обновление с помощью join.

Ответ №1:

Ваш @projid не инициализирован, и так оно и есть null . Итак, при выполнении if @proj_id!=@projid всегда возвращается значение false, поэтому вы никогда не входите в цикл.

Перед if убедитесь, что сделали что-то вроде SET @projid = -1 .

Комментарии:

1. Вы пропустили эту строку? FETCH NEXT FROM db_cursor_hierarchy_andreea INTO @projid,@parent_wbs_id

2. Я пропустил строку, но @projid все еще может быть нулевым, если нет никаких записей.

3. Это правда, было бы неплохо проверить @@FETCH_STATUS перед проверкой значения @projid .