【发布时间】: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 或类似的东西,新软件将使用它。但我宁愿避免这种情况。另外,当然,这让我毛骨悚然。我需要了解什么不再起作用,这样我才能评估我们的代码库中是否还有其他需要引起注意的地方。
更新开始
好的 - 这是我尝试过的
- 使用表变量@Table,在其中插入行,选择行。 结果:空数据表
- 使用固定表 [dbo].[TestTable]。显然不是生产解决方案,但我现在正在尝试。 SP 现在执行 DELETE [dbo].[TestTable]、INSERT INTO [dbo].[TestTable] 并最终选择行。 结果:空数据表
- 最后,我从 SP 中删除了所有插入和删除,并且只删除了 SELECT 行。 结果:DataTable 包含行
可能的结论:是 DELETE 和/或 INSERT 语句的存在导致了这种行为。
现在我需要做什么才能让它工作?为什么我用Adapter填DataTable不行,但是用同一个Adapter填DataSet就行了?
【问题讨论】:
-
去掉TAB别名有什么不同吗?
-
谢谢@JP .... 恐怕不是:(
-
更进一步。我对其进行了修改,因此它使用了一个实际的表,而不是表变量。没运气。我对其进行了简化,因此我确实对表变量进行了硬编码插入,然后进行了选择。没有运气。
-
@JP 我向 OP 添加了更新。也许这将有助于解释发生了什么?
-
可能是因为您使用 SelectCommand 但它有插入?你能用 SQLCommand 代替吗?
标签: vb.net stored-procedures datatable oledb