SQL Server: зачем мне добавлять «; 1» в конец имени хранимой процедуры? - PullRequest
12 голосов
/ 08 сентября 2010

Сегодня я столкнулся с проблемой совместимости, когда клиент обновился с Windows XP до Windows 7.

(12-летний код) вызывает на SQL Server хранимую процедуру с именем

ai_nextid

За исключением того, что когда он вызывает хранимую процедуру, он использует имя:

ai_nextid;1

Да, с добавлением ";1".Очевидно, что драйвер SQL Server в Windows 95, Windows 2000, Windows XP и, возможно, Windows Vista, подойдет для этого , в частности добавленного суффикса.Но драйвер ODBC для SQL Server в Windows 7 отличается и вызывает ошибку:

Общая ошибка SQL.
[Microsoft] [Драйвер ODBC SQL] [SQL Server] Не удалось найти хранимую процедуру'ai_nextid; 1'.
[Microsoft] [Драйвер ODBC SQL] [SQL Server] Переменная индикатора обязательна, но не указана ».

С собственной ошибкой 2812 .

Это поднимает 4 вопроса:

  • почему мы добавляли ;1 кконец имени хранимой процедуры?(что он делает)
  • почему драйвер SQL Server его игнорировал?
  • почему в Windows 7 было сделано критическое изменение?
  • задокументировано это изменение совместимости?

Последние два вопроса, вероятно, будут одинаковыми, так как, если они это задокументируют, они оправдают это.

Ответы [ 3 ]

13 голосов
/ 08 сентября 2010

см. CREATE PROCEDURE (Transact-SQL) документация по SQL Server 2008

--Transact-SQL Stored Procedure Syntax
CREATE { PROC | PROCEDURE } [schema_name.] procedure_name            [ ; number ]  <<<<<<
    [ { @parameter [ type_schema_name. ] data_type } 
        [ VARYING ] [ = default ] [ OUT | OUTPUT ] [READONLY]
    ] [ ,...n ] 
[ WITH <procedure_option> [ ,...n ] ]
[ FOR REPLICATION ] 
AS { [ BEGIN ] sql_statement [;] [ ...n ] [ END ] }
[;]

<procedure_option> ::= 
    [ ENCRYPTION ]
    [ RECOMPILE ]
    [ EXECUTE AS Clause ]

; число

Необязательное целое число, используемое для группировки процедурс таким же именем.Эти сгруппированные процедуры можно отбросить вместе с помощью одного оператора DROP PROCEDURE.

Примечание:

This feature will be removed in a future version of Microsoft SQL Server.
    Avoid using this feature in new development work, and plan to
    modify applications that currently use this feature.

Нумерованные процедуры не могут использовать пользовательские типы xml или CLR и не могут использоваться в планеруководство.

вы можете использовать это системное представление, чтобы найти все из них и начать переписывать их как отдельные процедуры:

sys.numbered_procedures (Transact-SQL)

6 голосов
/ 08 сентября 2010
  • почему мы добавляли 1 в конец имени хранимой процедуры? (что это делает)

; 1 означает, что вы вызываете номерные хранимые процедуры. Вы можете иметь InsertOrders;1, InsertOrders;2, InsertOrders;3 как разные версии с одинаковыми именами. Когда вы выполняете DROP для InsertOrders, все пронумерованные версии удаляются. Это была реализация перегрузки бедного человека.

  • почему драйвер SQL Server его игнорировал?

Старый драйвер SQL Server либо знал, что такое пронумерованный процесс, либо не был достаточно умен, чтобы анализировать и компилировать эту часть кода.

  • почему в Windows 7 были сделаны серьезные изменения?

  • документировано ли нарушение совместимости?

Это не будет поддерживаться в будущей версии, но R2 поддерживает нумерованные хранимые процедуры. Я лично никогда не выпускал пронумерованные проки в производство - только играл с ними, сказал "о круто" и пошел дальше.

0 голосов
/ 21 августа 2012

У меня была такая же проблема, пока я не добавил некоторый код, чтобы удалить «; 1», если он все еще был в конце StoredProcName:

strProcName := StoredProc.StoredProcName;

IF (length(strProcName) > 2) AND (copy(strProcName, length(strProcName) - 1, 2) = ';1') THEN

  BEGIN

    delete(strProcName, length(strProcName) - 1, 2);

    StoredProc.StoredProcName := strProcName;

  END {IF};

StoredProc.Prepare;

StoredProc.ParamByName('@cntid').AsInteger := nCounterID;

StoredProc.ParamByName('@range').AsInteger := nRange;

StoredProc.ExecProc;

result := StoredProc.ParamByName('@Status').AsInteger;
...