如何在动态查询中传递空值

时间:2017-01-18 07:37:29

标签: sql-server tsql sql-server-2012

我尝试执行以下动态查询,我只是将动态参数传递给此查询。

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+''''
PRINT   @SQL

但我无法获得任何结果或错误。 有人解决这个问题。

4 个答案:

答案 0 :(得分:1)

我没有将字符串连接在一起,而是添加了一个set语句,用字符串值或IS NULL替换@NAME变量。

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

答案 1 :(得分:0)

当您将NULL与字符串连接时,您将始终只获得NULL。这里变量@NAME为NULL,因此@SQL也将为NULL。

ISNULL为NULL时,您可以使用@NAME函数指定默认值。

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

但是你的查询中的另一个问题是,你不能在动态sql 中添加@Table_Variable,它会在你执行查询时抛出错误,但你可以在这里使用#Temp_tables。 / p>

答案 2 :(得分:0)

脚本有两个问题

1)将变量@Name设置为NULL。现在,当您将NULL与VARCHAR变量连接时,您的结果将变为NULL字符串。 因此,当包含SELECT语句的变量@SQL与@Name连接时,它变为NULL,并且在使用它与EXECUTE时,您的答案将不返回任何内容。

2)您正在声明一个表变量,该变量超出了EXECUTE语句的范围。在动态SQL中使用变量时,它们必须是:

  1. 与您尝试使用@Name变量的字符串连接,在这种情况下,传递变量的值并且值变为字符串的一部分而不是变量 DECLARE @Name VARCHAR(20) = 'ABC'; EXEC('SELECT ''' + @Name + ''';');
  2. 以上语句将执行以下SQL等效项:

    SELECT 'ABC';
    
    1. 在动态SQL语句中使用变量作为变量的另一种方法是仅在动态SQL中声明该变量。否则,在动态SQL中无法识别变量,并且在执行SQL字符串时会出现变量未声明的错误。正如您在执行语句时所看到的,SQL将无法从内部识别表变量@Table。 解决方法是在动态SQL字符串中声明@Table变量并在其中初始化它: 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='''+@NAME+'''';
    2. 要记住的一件重要事情是,动态SQL字符串将在与调用它的单独批处理中执行。这意味着如果我们在动态SQL字符串中声明@Table变量,那么它将仅存在于动态SQL字符串的持续时间和范围内,并且在此之后将不存在。因此,在动态SQL语句之后,对@Table变量所做的任何更改都不会出现,因为@Table变量将不再存在。 类似地,在SQL字符串之外声明@Table变量将阻止其在动态@SQL批处理中的使用。

答案 3 :(得分: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 '='''+@NAME+'''' END
PRINT @SQL