【问题标题】:sp_executesql returns nothing when parameter is null当参数为空时 sp_executesql 不返回任何内容
【发布时间】:2016-07-06 15:43:21
【问题描述】:

我的程序中有这段代码:

   SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #inserted'

   exec sp_executesql @Sql, N'@Value varchar(MAX) out', @NEW out


   SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #deleted'

   exec sp_executesql @Sql, N'@Value varchar(MAX) out', @OLD out

当列值为空时,变量@OLD没有任何内容,并且由于某种原因,当我比较这两个变量时:

IF @NEW != @OLD

它不会进入IF,即使@OLD 是空的而@NEW 不是。我试过这个:

IF @OLD is null or datalength(@OLD)=0 or @NEW != @OLD

但还是没有好的结果。当我打印 2 个变量时,@OLD 不打印任何内容(在表中为 null 的情况下)。

你能帮帮我吗?

谢谢你:)

编辑

这是我在数据库中的某些表更新时为它们构建的触发器,以便我可以保存所做的更改。为了方便起见,我通过该表的列名创建了一个循环,并且对于每一列,我都会执行一段代码,这给我带来了问题。这是我的更多触发器:

WHILE(@LoopCounter <= @MAX)
    BEGIN
       SELECT @Column = COLUMN_NAME, @Type = DATA_TYPE
       FROM INFORMATION_SCHEMA.COLUMNS WHERE ORDINAL_POSITION = @LoopCounter and TABLE_NAME = 'Parameters'

       SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #inserted'

       exec sp_executesql @Sql, N'@Value varchar(MAX) out', @NEW out


       SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #deleted'

       exec sp_executesql @Sql, N'@Value varchar(MAX) out', @OLD out

       IF @OLD is null or datalength(@OLD)=0 or @NEW != @OLD
       BEGIN
         /* some code */
       END

       SET @LoopCounter  = @LoopCounter  + 1 

END

【问题讨论】:

  • 你为什么在触发器中使用这样的动态sql?这是一个很大的危险信号,表明您的触发器内部进展不顺利。也许重新设计触发器是一种更好的方法。你能发布整个触发器吗?
  • 你有triggers标签有问题,这段代码是从触发器执行的吗?
  • @SeanLange 查看我对问题的更新。
  • @IvanStarostin 是的,它在表更新时执行。
  • 为了更简单???由于您现在发布了一个论坛问题来解决它,因此这对您来说变得更加困难。另一个影响是它的速度要慢得多。你真的应该考虑完全重写这个。

标签: sql sql-server stored-procedures triggers


【解决方案1】:

所以检查空状态:

IF @NEW != @OLD
OR @NEW IS NULL AND @OLD IS NOT NULL
OR @OLD IS NULL AND @NEW IS NOT NULL
BEGIN
...

【讨论】:

  • 我检查了 null 状态,但它仍然不起作用。
  • 我认为这实际上是不可能的。
【解决方案2】:

为什么不主动...如果您的@Column 为空,请不要执行..

WHILE(@LoopCounter <= @MAX)
    BEGIN
       SELECT @Column = COLUMN_NAME, @Type = DATA_TYPE
       FROM INFORMATION_SCHEMA.COLUMNS WHERE ORDINAL_POSITION = @LoopCounter and TABLE_NAME = 'Parameters'

       IF ISNULL(@Column,'')<>''
           BEGIN
           SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #inserted'

           exec sp_executesql @Sql, N'@Value varchar(MAX) out', @NEW out


           SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #deleted'

           exec sp_executesql @Sql, N'@Value varchar(MAX) out', @OLD out

           IF @OLD is null or datalength(@OLD)=0 or @NEW != @OLD
           BEGIN
             /* some code */
           END
       END
       SET @LoopCounter  = @LoopCounter  + 1 
END

【讨论】:

  • 列不是NULL,因为它是表的列名。它的值是可以为空的。
  • OK...但是您的问题确实表明...“当列值为 null 时,变量 @OLD 没有任何内容,并且由于某种原因,当我比较 2 个变量时:”。正如 Sean Lang 所提到的,您应该发布整个触发器,以便我们了解您要完成的工作,并可能为您提供尝试的选项。
【解决方案3】:

好的,我找到了解决方案。谢谢你的提示。我将代码更改为:

       SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #inserted'

       exec sp_executesql @Sql, N'@Value varchar(MAX) out', @NEW out


       SET @Sql = 'SELECT @Value = ' + @Column + ' FROM #deleted'

       exec sp_executesql @Sql, N'@Value varchar(MAX) out', @OLD out

       IF ISNULL(@NEW,0) != ISNULL(@OLD,0)

ISNULL一切正常。我还不得不在我的代码的另一个地方使用它,我将string@OLD@NEW值连接起来。

谢谢你:)

【讨论】:

  • 对于varchar 变量?
猜你喜欢
  • 1970-01-01
  • 2020-12-10
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-24
相关资源
最近更新 更多