2017-01-18 4 views
2

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

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME='''[email protected]+'''' 
PRINT @SQL 

Но я не могу получить никаких результатов или ошибок. не может решить эту проблему.

+0

Вы можете использовать ISNULL для @name, NULL контакт еще потому с любым значением будет по-прежнему является NULL –

+0

Почему динамический SQL вообще? –

+0

Просьба уточнить, если вы хотите намеренно передать значение NULL в запрос или задаетесь вопросом, почему запрос терпит неудачу. Если вы хотите передать NULL, нам нужно изменить строку, поскольку сравнение NULL не должно выполняться с помощью оператора '='. – DK5

ответ

0

Когда вы объединяете NULL со строкой, вы всегда получите только NULL. Здесь переменная @NAME равна NULL, поэтому @SQL также будет NULL.

Вы можете использовать функцию ISNULL, чтобы назначить значение по умолчанию, когда @NAME имеет значение NULL.

SET @SQL='SELECT * 
      FROM @TABLE 
      WHERE ISNULL(NAME,'''')='''+ISNULL(@NAME,'')+'''' 

Но другая проблема в вашем запросе, вы не можете добавить @Table_Variable внутри динамического SQL, это бросить ошибку при выполнении запроса, но вы можете использовать #Temp_tables здесь.

0

Есть два вопроса сценария

1) Вы установите переменную @name в NULL. Теперь, когда вы объединяете NULL с переменной VARCHAR, ваш результат становится NULL-строкой. Так как ваша переменная @SQL, содержащая оператор SELECT, объединяется с @Name, она становится NULL и, используя ее с EXECUTE, ваш ответ ничего не вернет.

2) Вы объявляете переменную таблицы, которая выходит за рамки инструкции EXECUTE. При использовании переменных с динамическим SQL, они должны быть:

  1. сцепленных со строкой, как вы пытались делать с переменной @name, в этом случае передается значение переменной и значение становится частью строка вместо переменного DECLARE @Name VARCHAR(20) = 'ABC'; EXEC('SELECT ''' + @Name + ''';');

вышеприведенного утверждения будет выполнить следующий SQL эквивалент:

SELECT 'ABC'; 
  1. другого способ использования переменной в качестве переменной из динамического оператора SQL состоит в том, чтобы объявить эту переменную только в динамическом SQL. В противном случае переменная не распознается в динамическом SQL, и вы получите необработанную ошибку переменной при выполнении вашей строки SQL. Как вы можете видеть, когда вы выполняете свой оператор, SQL не сможет распознать переменную таблицы @Table изнутри. Обойти это декларирует @Table переменную внутри динамической строки SQL и инициализации его там: DECLARE @NAME VARCHAR(20)=NULL, @SQL VARCHAR(MAX); SET @SQL='DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) INSERT INTO @TABLE SELECT 1,''A'' UNION SELECT 2,''B'' UNION SELECT 3,NULL; SELECT * FROM @TABLE WHERE NAME='''[email protected]+'''';

Одна важная вещь, чтобы помнить о том, что строка динамического SQL будет выполняться в отдельном пакете из в котором он был вызван. Это означает, что если мы объявим переменную @Table внутри динамической строки SQL, она будет существовать только для продолжительности и объема динамической строки SQL и не будет существовать после этого. Поэтому любые изменения, которые вы вносите в переменную @Table, не будут присутствовать после динамического оператора SQL, поскольку переменная @Table больше не будет существовать. Аналогично объявление переменной @Table за пределами строки SQL предотвратит ее использование в динамической пакетной версии @SQL.

0

Вы не можете получить доступ к переменной таблицы в инструкции EXEC.Поскольку переменная таблицы специфична для области подключения. Оператор Exec выполнит код в другом сеансе (соединение).

Так вместо этого вы можете использовать временную таблицу (#)

CREATE TABLE #TABLE (ID INT,NAME VARCHAR(10)) 
INSERT INTO #TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM #TABLE 
        WHERE NAME ' 
SELECT @SQL = @SQL + CASE WHEN @NAME IS NULL THEN 'IS NULL' ELSE '='''[email protected]+'''' END 
PRINT @SQL 
0

Вместо конкатенации строки вместе, я добавил множество заявление, чтобы заменить переменную @name либо строковое значение или IS NULL.

DECLARE @TABLE TABLE(ID INT,NAME VARCHAR(10)) 
INSERT INTO @TABLE 
SELECT 1,'A' 
UNION 
SELECT 2,'B' 
UNION 
SELECT 3,NULL 

DECLARE @NAME VARCHAR(20)=NULL, 
     @SQL VARCHAR(MAX) 
     SET @SQL='SELECT * 
        FROM @TABLE 
        WHERE NAME [NAME]' 
set @SQL = replace(@SQL, '[NAME]', isnull('= ''' + @NAME + '''', 'IS NULL')) 
print @SQL 
Смежные вопросы