如何观察SET CONCAT_NULL_YIELDS_NULL的效果?

问题描述 投票:2回答:3

我们有一个旧的数据库产品;主部署总是做ALTER Database [databasename] SET CONCAT_NULL_YIELDS_NULL OFF。由于此设置已经消失,我们希望提出一个测试计划,以摆脱它并跟踪代码依赖于它。

关闭此开关后,文档说SELECT 'abc' + NULL FROM sometable导致abc而不是NULL。

我可以在连接级别轻松地观察到这种行为;但是应用程序从不在连接级别设置它。这不是问题。

我如何通过任何SQL语句观察使用.NET CONCAT_NULL_YIELDS_NULL作为数据库访问客户端仅在数据库级别关闭System.Data.SqlClient的效果?

我们审核了整个代码库并删除了除事务隔离级别之外的所有SET命令实例,因为这些软件非常困难。虽然我尝试EXEC看它是否会绕过驱动程序设置并发现它没有,但我有理由相信有一些充满异国情调的SQL构造可能会成功。

sql-server tsql sqlclient
3个回答
1
投票

我想我终于理解了你真正想要的东西:改变连接选项而不改变它。不,没有办法实现这一点,否则我会听说过他们,而Rutzky会在我原来回答中提到的答案中提到他们。

可以设置选项的方式有严格的层次结构:

  1. 使用sp_configure 'user options'的所有数据库的实例范围设置。最低级别的默认值。
  2. 特定于数据库的选项,可以通过ALTER DATABASE设置。优先于实例默认值。
  3. 在连接上执行的显式SET语句。覆盖一切。

建议?如果可以,请更改应用程序的连接字符串,以便它使用另一个未设置/触摸此选项的驱动程序。当然,假设它不会崩溃,但这是一个可以相对快速地测试的东西。

此外,您可以尝试更改实例默认值,并查看驱动程序是否以某种方式优先于#2。它本身可能太聪明了。


附:为了完整起见,我所知道的唯一相互依赖的选项列表如下:

  1. 快捷方式设置,例如ANSI_DEFAULTS。设置它实际上会影响与ANSI兼容性相关的几个选项;
  2. SET LANGUAGE。当您更改连接语言时,它还会覆盖DATEFIRSTDATEFORMAT选项。

P.P.S.我决定完整地保留我之前的答案,因为它仍然包含一些信息,这些信息可能对那些以我最初的方式理解你的问题的人有用。


0
投票

即使您的应用程序未明确指定此选项,不同的ODBC和OLEDB驱动程序也具有不同的连接选项默认值。根据驱动程序的不同,此特定选项可以隐式设置,也可以从数据库/服务器设置继承。

为了查看应用程序建立的连接的此选项的实际状态,您可以使用setup a Profiler trace显示有效的连接设置。

关于覆盖驱动程序的行为设置此选项,在DBA StackExchange上有类似问题的相当thorough answer。在那里,您可以找到几种可能的方法,并查看哪种方法最适合您。

在SQL方面,一种可能的解决方案是将旧样式的+字符串连接替换为自SQL Server 2012以来可用的较新的concat()函数。此函数在连接期间跳过NULL参数,因此结果总是看起来好像concat_null_yields_null设置为off。根据系统中SQL代码模块的数量,这可能是一项艰巨的工作,尤其是因为很难用肉眼区分数字加法和字符串连接。

我建议你去购买一些代码分析/重构工具,这些工具可能会对此有所帮助。不确定SSDT是否具备此功能,但我会先从它开始,因为它是免费的(尝试2天前发布的Visual Studio 2019可能是有意义的 - 那里可能有些东西)。除此之外,好吧...... RedGate,Idera,ApexSQL,你的名字。有人可能已经这样做了。


-1
投票

这可以通过此查询来实现

IF (SELECT ''+NULL) IS NULL
BEGIN
    SET CONCAT_NULL_YIELDS_NULL OFF
END
ELSE
BEGIN
    SET CONCAT_NULL_YIELDS_NULL ON
END
© www.soinside.com 2019 - 2024. All rights reserved.