我们有一个旧的数据库产品;主部署总是做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构造可能会成功。
我想我终于理解了你真正想要的东西:改变连接选项而不改变它。不,没有办法实现这一点,否则我会听说过他们,而Rutzky会在我原来回答中提到的答案中提到他们。
可以设置选项的方式有严格的层次结构:
sp_configure 'user options'
的所有数据库的实例范围设置。最低级别的默认值。ALTER DATABASE
设置。优先于实例默认值。SET
语句。覆盖一切。建议?如果可以,请更改应用程序的连接字符串,以便它使用另一个未设置/触摸此选项的驱动程序。当然,假设它不会崩溃,但这是一个可以相对快速地测试的东西。
此外,您可以尝试更改实例默认值,并查看驱动程序是否以某种方式优先于#2。它本身可能太聪明了。
附:为了完整起见,我所知道的唯一相互依赖的选项列表如下:
ANSI_DEFAULTS
。设置它实际上会影响与ANSI兼容性相关的几个选项;SET LANGUAGE
。当您更改连接语言时,它还会覆盖DATEFIRST
和DATEFORMAT
选项。P.P.S.我决定完整地保留我之前的答案,因为它仍然包含一些信息,这些信息可能对那些以我最初的方式理解你的问题的人有用。
即使您的应用程序未明确指定此选项,不同的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,你的名字。有人可能已经这样做了。
这可以通过此查询来实现
IF (SELECT ''+NULL) IS NULL
BEGIN
SET CONCAT_NULL_YIELDS_NULL OFF
END
ELSE
BEGIN
SET CONCAT_NULL_YIELDS_NULL ON
END