如何观察关闭SET CONCAT_NULL_YIELDS_NULL的效果?

时间:2019-04-01 23:09:08

标签: sql-server tsql sqlclient

我们有一个旧的数据库产品;主部署始终完成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构造可以成功。

3 个答案:

答案 0 :(得分:1)

我想我终于了解了您的实际需求:更改连接选项而不更改它。 不,没有办法实现这一目标,否则我会听说过它们,鲁兹基也会在我在原始回复中引用的答案中提到它们。

在设置选项方面存在严格的层次结构:

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

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

此外,您可以尝试更改实例默认值,并查看驱动程序是否以某种方式使它们优于#2。为了自己的利益,它可能太聪明了。


P.S。为了完整起见,下面列出了我所知的相互依赖选项的唯一情况:

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

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

答案 1 :(得分: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,请给它命名。可能有人已经这样做了。

答案 2 :(得分:-1)

这可以通过此查询来实现

IF (SELECT ''+NULL) IS NULL
BEGIN
    SET CONCAT_NULL_YIELDS_NULL OFF
END
ELSE
BEGIN
    SET CONCAT_NULL_YIELDS_NULL ON
END