如何观察 SET CONCAT_NULL_YIELDS_NULL off 的效果?

How can I observe the effect of SET CONCAT_NULL_YIELDS_NULL off?

我们有一个旧的数据库产品;主部署始终完成 ALTER Database [databasename] SET CONCAT_NULL_YIELDS_NULL OFF。由于此设置即将消失,我们想制定一个测试计划来摆脱它并追踪依赖它的代码。

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

我可以很容易地在连接级别观察到这种行为;但是应用程序 never 在连接级别设置它。这不是这里的问题。

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

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

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

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

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

在 SQL 方面,一种可能的解决方案是用更新的 concat() 函数替换旧式 + 字符串连接,该函数自 SQL Server 2012 起可用。此函数在串联期间跳过 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

我想我终于明白你真正想要的是什么:改变连接选项而不改变它。 不,没有办法实现这个,否则我会听说过它们,而 Rutzky 会在他的回答中提到它们,我在我的原始回复中引用了它们。

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

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

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

此外,您可以尝试更改实例默认值,并查看驱动程序是否以某种方式偏爱它们而不是 #2。它可能太聪明了。


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

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

P.P.S。我决定原封不动地保留我之前的回答,因为它仍然包含一些信息,这些信息可能对那些会像我最初那样理解你的问题的人有用。