【问题标题】:Different behaviour of postgresql and firebird recordsetspostgresql 和 firebird 记录集的不同行为
【发布时间】:2015-07-19 19:36:54
【问题描述】:

这个问题与我之前问过的一个问题here 有关。

对 firebird 数据库的查询检索到单行记录集,因为 Where 子句包含主键。 然而,在随后的更新中,几乎表中的每一行都被更新了。 我一直期待只更新一行。 这是查询:

sQuery = "select memo from clients where clientID = 10021 "

发生的事情似乎是选择查询需要包含 记录集中的主键列,以便将更新限制为仅一条记录。

sQuery = "select memo, clientID from clients where clientID = 10021 "

但是在 postgresql 中,第一个查询的工作方式与第二个查询在 firebird 中的工作方式相同。

我可以依赖 postgresql 中的这种行为还是应该重写现有查询以包含 记录集中随后将更新的主键列?

有没有办法让 firebird 查询的行为与 postgresql 一样?

虽然我现在可以看到火鸟行为的逻辑,但它不是 我习惯了 MSAccess/DAO 背景。

我真的只是想知道发生了什么,以及 ADO 记录集所期望的更“正常”的行为是什么?

这是使用 firebird 的完整代码。

'FIREBIRD
'vb6 and ms ado 2.8
'windows 7 home edition 64 bit
'Firebird version is 2.5.4.26856 (x64).
'Firebird ODBC driver 2.0.3.154

    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    Dim cs As String
    Dim dbPath As String

    dbPath = "c:\Parkes\Parkes.fdb"
    cs = "DRIVER={Firebird/Interbase(r) Driver}; DBNAME=localhost:" & dbPath & "; UID=SYSDBA; PWD=masterkey;"
    cn.ConnectionString = cs
    cn.Open

    Dim sQuery As String

    sQuery = "select memo from clients where clientID = 10021 "
    rs.Open sQuery, cn, adOpenStatic, adLockOptimistic

    If rs.BOF <> True Or rs.EOF <> True Then
    'putting msgbox rs.recordcount here confirms only 1 record in recordset
        rs.Movefirst
        rs.Fields("memo") = "blah"
        rs.Update

    End If

    Set rs = Nothing
    Set cn = Nothing

这是使用 postgresql 数据库的相同代码;

'POSTGRESQL
'vb6 and ms ado 2.8
'windows 7 home edition 64 bit
Postgresql version is 9.4 64 bit
psql ODBC driver 9.3.4

    Dim cn As New ADODB.Connection
    Dim rs As New ADODB.Recordset

    Dim cs As String
    Dim dbPath As String

    dbPath = "c:\Parkes\Parkes.fdb"
   cs = "Driver={PostgreSQL ANSI};SERVER=localhost;Port=5432;DATABASE=Parkes;UID=postgres;PWD=masterkey;CONNSETTINGS=SET Datestyle TO 'DMY'%3b;BOOLSASCHAR=0;TEXTASLONGVARCHAR=1;TrueIsMinus1=1;"

    cn.ConnectionString = cs
    cn.Open

    Dim sQuery As String

    sQuery = "select memo from clients where clientID = 10021 "
    rs.Open sQuery, cn, adOpenStatic, adLockOptimistic

    If rs.BOF <> True Or rs.EOF <> True Then
    'putting msgbox rs.recordcount here confirms only 1 record in recordset
        rs.Movefirst
        rs.Fields("memo") = "blah"
        rs.Update

    End If

    Set rs = Nothing
    Set cn = Nothing

【问题讨论】:

    标签: postgresql vb6 ado firebird


    【解决方案1】:

    根据回复 here 和链接到那里的 microsoft article,firebird odbc 驱动程序的设计似乎与(大多数?)其他 odbc 驱动程序不同。

    Microsoft ADO API 参考声明 Update 方法应该只更新当前记录。

    Firebird 驱动程序的工作方式不同,通过一些示例更容易解释如何

    在下面的例子中,记录集只包含一条记录(因为 clientid 是主键,因此是唯一的)并假设它的 memo 字段中的值是'bingo'。 update 方法会将表中现有值为 'bingo' 的所有行的备注字段值更改为 'blah'。

    sQuery = "select memo from clients where clientID = 10021 "
        rs.Open sQuery, cn, adOpenStatic, adLockOptimistic
    
        If rs.BOF <> True Or rs.EOF <> True Then
            rs.Movefirst
            rs.Fields("memo") = "blah"
            rs.Update
    
        End If
    

    在下一个示例中,记录集再次仅包含一条记录,但现在包含 2 列,并假设其备注字段中的值为“bingo”,其姓氏字段中的值为“Jones”。 update 方法会将表中所有行的 memo 字段值更改为“blah”,这些行的现有值在其 memo 字段中具有“bingo”,在其 surname 字段中具有“Jones”。

    sQuery = "select memo, surname from clients where clientID = 10021 "
        rs.Open sQuery, cn, adOpenStatic, adLockOptimistic
    
        If rs.BOF <> True Or rs.EOF <> True Then
            rs.Movefirst
            rs.Fields("memo") = "blah"
            rs.Update
    
        End If
    

    显然,这可能仍然不会将更新限制为一行。 为确保只更新一行,您需要在记录集中包含具有唯一值的列,例如主键列:

    sQuery = "select memo, clientID from clients where clientID = 10021 "
            rs.Open sQuery, cn, adOpenStatic, adLockOptimistic
    
            If rs.BOF <> True Or rs.EOF <> True Then
                rs.Movefirst
                rs.Fields("memo") = "blah"
                rs.Update
    
            End If
    

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 2012-06-08
      • 2018-01-30
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 2020-10-23
      • 2017-06-22
      • 1970-01-01
      相关资源
      最近更新 更多