Правильно установить CONCAT_NULL_YIELDS_NULL и ANSI_WARNINGS ON внутри хранимой процедуры - PullRequest
1 голос
/ 31 марта 2020

У меня есть таблица с индексом, который требует, чтобы CONCAT_NULL_YIELDS_NULL и ANSI_WARNINGS были включены. Вот моя хранимая процедура для обновления значения в этой таблице.

SET CONCAT_NULL_YIELDS_NULL ON;
SET ANSI_WARNINGS ON;
GO
CREATE OR ALTER PROCEDURE My_Procedure
    @Namespace VARCHAR(50),
    @Name VARCHAR(50),
    @Value VARCHAR(255)
AS
BEGIN TRAN
    SET ANSI_WARNINGS ON;
    SET CONCAT_NULL_YIELDS_NULL ON;
    UPDATE MyTable SET Value = @Value WHERE Namespace = @Namespace AND Name = @Name;
COMMIT TRAN

Но когда я exec [My_Procedure] @Namespace='my namespace', @name='my name', @value='sp value'

получаю:

ОБНОВЛЕНИЕ не удалось, поскольку следующие параметры SET имеют неправильные настройки: 'CONCAT_NULL_YIELDS_NULL, ANSI_WARNINGS' , Убедитесь, что параметры SET верны для использования с индексированными представлениями и / или индексами для вычисляемых столбцов и / или отфильтрованных индексов и / или уведомлений о запросах и / или XML методов типа данных и / или операций с пространственным индексом.

Если я сделаю

set ansi_warnings on;
set concat_null_yields_null on;
exec [My_Procedure] @Namespace='my namespace', @name='my name', @value='sp value'

, то это будет работать без ошибок. Но я ожидаю, что, поместив эти команды в хранимую процедуру, это сработает. Чего мне не хватает?

Ответы [ 2 ]

0 голосов
/ 01 апреля 2020

Если вы закомментируете обновление и добавите DBCC USEROPTIONS для отображения настроек во время выполнения pro c, вы увидите, что параметры установлены правильно во время выполнения. То есть:

CREATE OR ALTER PROCEDURE My_Procedure
    @Namespace VARCHAR(50),
    @Name VARCHAR(50),
    @Value VARCHAR(255)
AS
BEGIN TRAN;
    SET ANSI_WARNINGS ON;
    SET CONCAT_NULL_YIELDS_NULL ON;
    --UPDATE MyTable SET Value = @Value WHERE Namespace = @Namespace AND Name = @Name;
    DBCC USEROPTIONS;
COMMIT TRAN;
GO

--set required options off for illustration
SET CONCAT_NULL_YIELDS_NULL OFF;
SET ANSI_WARNINGS OFF;
EXEC [My_Procedure] @Namespace='my namespace', @name='my name', @value='sp value'
GO

Результаты:

+-------------------------+----------------+
|       Set Option        |     Value      |
+-------------------------+----------------+
| textsize                | 2147483647     |
| language                | us_english     |
| dateformat              | mdy            |
| datefirst               | 7              |
| lock_timeout            | -1             |
| quoted_identifier       | SET            |
| arithabort              | SET            |
| ansi_null_dflt_on       | SET            |
| ansi_warnings           | SET            |
| ansi_padding            | SET            |
| ansi_nulls              | SET            |
| concat_null_yields_null | SET            |
| isolation level         | read committed |
+-------------------------+----------------+

Вы получите ошибку в время компиляции , если вы раскомментируете UPDATE ; SET операторы в коде pro c никогда не выполняются в этом случае.

Современные SQL Серверные API-интерфейсы по умолчанию правильно устанавливают "magi c 7", устанавливаемые параметры (включая упомянутые "липкие" @AlwaysLearning). Следовательно, обычно не требуется устанавливать их в pro c коде. Возможно, вы используете очень устаревший API или неправильно установили параметры в настройках кода или клиентского инструмента.

0 голосов
/ 01 апреля 2020

Хранимые процедуры имеют особые особенности для операторов SET, например:

Хранимые процедуры выполняются с настройками SET, указанными во время выполнения, за исключением SET ANSI_NULLS и SET QUOTED_IDENTIFIER. Хранимые процедуры, указывающие SET ANSI_NULLS или SET QUOTED_IDENTIFIER, используют настройку, указанную во время создания хранимой процедуры. Если используется внутри хранимой процедуры, любая настройка SET игнорируется.

REF: Замечания по использованию инструкций SET

Хотя SET NOCOUNT ON/OFF работает внутри хранимых процедур, что противоречит вышеуказанному.

...