使用 SQLOLEDB 或 MSDASQL 的一条 SQL 语句产生不同的结果

Nik*_* B. 3 sql-server backup profiler t-sql

我将 VB6 与 SQLOLEDB 和 MSDASQL 一起使用。通过切换提供程序,我注意到一次查询得到了不同的结果。

我的查询检查一些服务器设置并执行两个 BACKUP 语句之一。

当我使用 SQLOLEDB 时,一切正常并且备份被创建。如果我使用的是 MSDASQL,则不会发生错误,但不会创建备份。

这是同一个服务器、同一个用户和同一个语句。

我使用过 SQL Profiler,它显示 100% 执行了相同的命令。即使我复制 MSDASQL 命令并在 SSMS 中执行它,也会创建备份,但不会使用 VB6。

我的声明:

DECLARE @s varchar(1000), @ver int
SET @ver = 10
SELECT @s = case
WHEN
@ver > 9
THEN
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  COMPRESSION, NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10'
ELSE
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10;'
END
EXEC (@s)
Run Code Online (Sandbox Code Playgroud)

但是当我执行时:

DECLARE @s varchar(1000), @ver int
SELECT @s = case
WHEN
10 > 9
THEN
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  COMPRESSION, NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10'
ELSE
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10;'
END
EXEC (@s)
Run Code Online (Sandbox Code Playgroud)

(没有 SET @ver = 10)备份有效。

有人能解释一下吗?

Dan*_*man 5

通过 ADO 的 OLEDB 一直存在 DONE_IN_PROC 消息(受影响的行)混淆不期望它们的代码的问题。不更改应用程序代码的解决方法是将 SET NOCOUNT ON 指定为批处理中的第一条语句:

SET NOCOUNT ON;
DECLARE @s varchar(1000), @ver int;
SET @ver = 10;
SELECT @s = case
WHEN
@ver > 9
THEN
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  COMPRESSION, NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10'
ELSE
'BACKUP DATABASE [DB] TO DISK = ''C:\SQL Backup\Backup.dat'' WITH  NOFORMAT, NOINIT, SKIP, REWIND, NOUNLOAD, STATS = 10;'
END;
EXEC (@s)
Run Code Online (Sandbox Code Playgroud)

编辑:

完成每个 T-SQL 语句和过程后,将向客户端返回TDS 协议DONEDONEINPROCDONEPROC消息。这些消息可以选择包含行计数(由DONE_COUNT标志指示)。像 ADO 这样的高级 API 通常会忽略这些 TDS 消息,除非包含行计数。但是在这种情况下,ADO 有一个讨厌的习惯,即返回没有列或行的结果集。这种行为不仅可能因提供者/驱动程序而异,而且当生成信息和错误消息但客户端未使用时,情况会变得更加复杂。这可能会导致多语句批处理无法运行完成和未检测到错误。

SET NOCOUNT ON 是一种避免这些问题的便捷方法,而不是编写代码来处理所有消息并跳过这些空结果集。

我应该补充一点,这适用于非托管的“经典”ADO,而不是 ADO.NET。