2015-10-03 32 views
4

在Npgsql V2中,我可以使用以下代码更新记录,并使用单个Npgsql命令返回更新的记录值。带多条语句的Npgsql命令

command.CommandText属性包含一个UPDATE语句和一个SELECT语句。这个想法是,当调用command.ExecuteReader时,两个命令都会运行,但是返回SELECT命令的结果(因为它是最后一个命令)。

升级到Npgsql版本3.0.3.0后,数据读取器中的值(来自SELECT语句)仍然是原始值,而不是更新的值(代码中的Return dr("action")行)。我已经尝试了每种不同的IsolationLevel,并且它们都给出了相同的结果(就好像SELECT语句没有从INSERT语句中看到更新的值)。该值在数据库中正确更新(如果我重新查询它具有更新值的记录)。

我可以拆分这个,并使用两个单独的NpgsqlCommand(一个用于INSERT,另一个用于SELECT),但我不想创建第二个往返服务器。

这是一个简化的函数,实际功能的目的是更新数据库服务器上的记录,然后使用服务器更新的任何其他字段更新应用程序中的对象(例如“last_updated”时间戳每次更新记录时在服务器上更新的字段)。

有没有办法让这个工作与Npgsql V3.0.3.0?

Public Function UpdateRecordExample(id As Guid, newAction As String) As String 
     Using conn As New NpgsqlConnection("Connection String Here") 
      Using trans = conn.BeginTransaction(IsolationLevel.ReadUncommitted) 
       Dim command = conn.CreateCommand 
       command.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord 
       command.CommandText = "Update pm.action_item SET [email protected] WHERE [email protected]; SELECT * FROM pm.action_item WHERE [email protected];" 
       command.Parameters.Add(New NpgsqlParameter("id", id)) 
       command.Parameters.Add(New NpgsqlParameter("action", newAction)) 
       Using dr = command.ExecuteReader 
        If dr.Read Then 
         Return dr("action") 'This is still the original value and not "newAction" 
        Else 
         Throw New DBConcurrencyException 
        End If 
       End Using 
      End Using 
     End Using 
    End Function 
+0

感谢张贴这个,它绝对不应该发生。我正在研究PostgreSQL开发者的事情,并会尽快回复。 –

+0

虽然这并不能真正回答你的问题,但我真的建议避免这样的多语句。另外,你确定你正在避免往返? PgJDBC至少分割多个语句并分别执行每个语句。 nPgSQL也可能。理想情况下你应该做什么 - 如果nPgSQL与PgJDBC具有类似的接口,则发出一批语句。如果nPgSQL不支持批处理,可能值得为它们添加支持;这样做可能不那么困难,并且性能提升是巨大的。 –

+0

@ShayRojansky你可以确认这个概念是否有效,真的会避免第二次往返?我注意到NpgsqlCommand对象确实将命令文本分成多个语句(这几乎就像每个语句并行运行而不是顺序运行)。我认为向NpgsqlCommand.CommandText添加多个语句就像发出一批连续语句一样。 – Casey

回答

0

请注意,此问题已在Npgsql 3.1中解决。

+0

工程很棒。感谢您和Npgsql团队的其他成员为您所做的出色工作。 – Casey