Известная проблема ?: Не удается завершить хранимую процедуру SQL Server 2005 с параметром - PullRequest
4 голосов
/ 18 декабря 2008

Ваш базовый SP с параметром по умолчанию:

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID AS int = 20081130
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] WITH RECOMPILE
    */
    -- Stuff here that depends on DATA_DT_ID
END

Тот же SP с локальным кодом, который жестко закодирован.

ALTER PROCEDURE usp_debug_works]
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_works] WITH RECOMPILE
    */

    DECLARE @DATA_DT_ID AS int
    SET @DATA_DT_ID = 20081130
    -- Stuff here that depends on DATA_DT_ID
END

Вы можете видеть, куда я добавляю (избыточные, четные) опции WITH RECOMPILE, чтобы избежать перехвата параметров (это никогда не было необходимо при разработке, где эта штука работала нормально)

Тот, который работает, завершается нормально через минуту или две, другой никогда не завершается - просто сидит там часами.

Эта проблема никогда не возникала на сервере разработки (сборка 9.00.3282.00), рабочий сервер - сборка 9.00.3068.00

Я удалил все виды кода из процедур, чтобы попытаться перейти к минимальной версии, которая все еще демонстрирует проблему, и очень тщательно следил за тем, чтобы обе версии SP были одинаковыми, за исключением этого одного параметра.

У меня есть много других SP, которые принимают параметры, и они работают нормально. Я также DROP ped и re CREATE ed SPs.

Есть идеи?

И да, у меня есть администратор базы данных, который смотрит на него, и у меня нет SHOWPLAN или каких-либо полезных прав на производство, чтобы увидеть, есть ли блокировка (в случае, если чей-то план приводит к эскалации блокировки, я думаю - опять-таки, единственная разница параметр)

Я просмотрел всю информацию о сборке SQL Server и не вижу известной проблемы по этому поводу, поэтому, пока я не выясню это или администратор базы данных не выяснит, я как-то застрял.

UPDATE

Это также не может быть завершено (на самом деле это нормальная форма для этих SP - я просто ввел значение по умолчанию, чтобы упростить переключение назад и вперед во время тестирования)

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID AS int
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] 20081130 WITH RECOMPILE
    */
    -- Stuff here that depends on DATA_DT_ID
END

однако этот завершает (который может работать как обходной путь, хотя у меня есть около 25 из этих SP для модификации, которые имеют одинаковую форму):

ALTER PROCEDURE [usp_debug_fails]
    @DATA_DT_ID_in AS int
WITH RECOMPILE
AS
BEGIN
    /*
        Usage:
        EXEC [usp_debug_fails] 20081130 WITH RECOMPILE
    */

    DECLARE @DATA_DT_ID AS int
    SET @DATA_DT_ID = @DATA_DT_ID_in
    -- Stuff here that depends on DATA_DT_ID
END

Ответы [ 2 ]

2 голосов
/ 18 декабря 2008

Попробуйте замаскировать входной параметр.

Я полагаю, что перекомпиляция не работает из-за того, что заданное значение по умолчанию ( EDIT : или параметр, отправленный при первом вызове) прослушивается во время компиляции. Таким образом, перекомпиляция не имеет никакого эффекта.

Я видел огромную разницу между оценочными планами, просто изменив значение по умолчанию, скажем, с нуля на NULL или не имея такового.

ALTER PROCEDURE [usp_debug_mightwork]
    @DATA_DT_ID AS int = 20081130
AS
BEGIN
    DECLARE @IDATA_DT_ID AS int
    SET @IDATA_DT_ID = @DATA_DT_ID
    -- Stuff here that depends on IDATA_DT_ID
END

Я думаю эта статья объясняет ...

... значения параметров снимаются во время компиляция или перекомпиляция ...

EDIT:

Новая ссылка на планы запросов и параметры . Это все еще параметр, определяющий, задано ли значение по умолчанию.

Параметр WITH RECOMPILE указан для хранимая процедура GetRecentSales выше не исключает ошибка оценки мощности

Вид статьи о константах и ​​планах

0 голосов
/ 20 декабря 2008

Предотвращение перехвата параметров или тост при изменении статистики. У меня 500+ спов, и все они начинаются с:

DECLARE @_Param1 ..., @_ParamN

--- prevent pameter sniffing
SELECT @_Param1 = @Param1, @_ParamN = @ParamN

...