【问题标题】:Empty Table returned after minor modification to a Stored Procedure对存储过程进行微小修改后返回的空表
【发布时间】:2020-01-30 14:52:21
【问题描述】:

更新见 OP 结尾

这个让我们摸不着头脑。

我们在 VB.NET 中编写了一个填充 DataTable 的方法

它执行以下操作(简化 - 实例化或设置项目的代码并删除错误处理)

Dim procedureName As String
Dim mnCommandTimeOut As Integer
Dim parameters As System.Data.OleDb.OleDbParameter()
Dim oConnection As System.Data.OleDb.OleDbConnection

'... 以上所有内容都将在中间代码中设置。那么

Dim dataTable As System.Data.DataTable = Nothing
Dim oCommand As System.Data.OleDb.OleDbCommand = Nothing
oCommand = New System.Data.OleDb.OleDbCommand(procedureName, oConnection)
oCommand.CommandType = CommandType.StoredProcedure
oCommand.CommandTimeout = mnCommandTimeout

If parameters IsNot Nothing Then
    oCommand.Parameters.AddRange(parameters)
End If

Dim oAdapter As System.Data.OleDb.OleDbDataAdapter = Nothing
oAdapter = New System.Data.OleDb.OleDbDataAdapter()
oAdapter.SelectCommand = oCommand    

oAdapter.SelectCommand.CommandTimeout = 120
oAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey
oAdapter.MissingMappingAction = MissingMappingAction.Passthrough
dataTable = New System.Data.DataTable()

oAdapter.Fill(dataTable)

请注意,我还遗漏了我们自己清理的代码,处理我们不再需要的东西等等。我们的真实代码比这更干净!

问题来了

我有一个使用上述方法调用的 SP。同样,我不会涉及任何复杂性,但 SP 中的代码基本上包含类似

SELECT Column1,
       Column2
  FROM <somequery>

现在我需要对这个 SP 进行修改,并增加了一些复杂性

DECLARE @Table TABLE
       (Column1 <some type here>  PRIMARY KEY NOT NULL,
        Column2 <some type here>              NOT NULL)

列类型匹配原始类型

INSERT
  INTO @Table
      (Column1,
       Column2)
SELECT <modified query>

紧随其后

SELECT [TAB].[Column1],
       [TAB].[Column2]
  FROM @Table [TAB]

总结除了使用表变量之外,我还没有对 SP 进行任何重大更改。我不直接执行SELECT,而是INSERT INTO 表变量,然后从中SELECT。我还没有介绍任何我需要的额外复杂性;当我通过 SQL Server Management Studio 运行旧 SP 和新 SP 时,我仍然得到相同的输出 那里

但不是通过VB.NET中的上述代码

使用旧的 SP,我得到一个 System.Data.DataTable,其中包含 SP 返回的所有行 使用新的 SP,我得到一个 System.Data.DataTable,其中包含 0 列和 0 行。

不会引发任何错误 代码运行良好。它只是返回一个空表。

情况变得更糟。我们还有另一种填充 DataSet 的方法。它与原始程序的唯一区别是我们定义了

Dim dataSet As System.Data.DataSet = Nothing
dataSet = New System.Data.DataSet()

oAdapter.Fill(dataSet)

这是疯狂的一点。完全无法理解的疯狂位。

当我通过 dataset 方法运行修改后的 SP 时,它会返回一个数据集。数据集包含一个数据表,猜猜看,数据表包含我的 SP 返回的所有数据。

我很困惑。 地球到底发生了什么?有人有线索吗?我怀疑这与我使用表变量有关,但是什么,怎么做?

我知道你要说什么:我们为什么不直接使用 DataSet 方法?当然。但我们承诺向后兼容。可能有旧版本的代码,调用我的SP,使用旧方法。我设计了我的 SP,以便它仍然返回旧版本代码所期望的所有相同数据。但我不能更改旧版本的代码。他们仍然使用使用 DataTable 的方法。所以我不能给他们一个不适合他们工作的SP。

当然还有另一种解决方案。保持旧 SP 不变。编写一个新版本的 SP,originalnamev2 或类似的东西,新软件将使用它。但我宁愿避免这种情况。另外,当然,这让我毛骨悚然。我需要了解什么不再起作用,这样我才能评估我们的代码库中是否还有其他需要引起注意的地方。

更新开始

好的 - 这是我尝试过的

  1. 使用表变量@Table,在其中插入行,选择行。 结果:空数据表
  2. 使用固定表 [dbo].[TestTable]。显然不是生产解决方案,但我现在正在尝试。 SP 现在执行 DELETE [dbo].[TestTable]、INSERT INTO [dbo].[TestTable] 并最终选择行。 结果:空数据表
  3. 最后,我从 SP 中删除了所有插入和删除,并且只删除了 SELECT 行。 结果:DataTable 包含行

可能的结论:是 DELETE 和/或 INSERT 语句的存在导致了这种行为。

现在我需要做什么才能让它工作?为什么我用Adapter填DataTable不行,但是用同一个Adapter填DataSet就行了?

【问题讨论】:

  • 去掉TAB别名有什么不同吗?
  • 谢谢@JP .... 恐怕不是:(
  • 更进一步。我对其进行了修改,因此它使用了一个实际的表,而不是表变量。没运气。我对其进行了简化,因此我确实对表变量进行了硬编码插入,然后进行了选择。没有运气。
  • @JP 我向 OP 添加了更新。也许这将有助于解释发生了什么?
  • 可能是因为您使用 SelectCommand 但它有插入?你能用 SQLCommand 代替吗?

标签: vb.net stored-procedures datatable oledb


【解决方案1】:

此行为是由于我的 SP 在顶部缺少 SET NOCOUNT ON 语句引起的。一旦我添加了它,它就会再次起作用。

【讨论】:

    猜你喜欢
    • 2021-11-23
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多