postgresql和firebird记录集的不同行为

时间:2015-05-08 19:24:48

标签: postgresql vb6 ado firebird

这个问题与我之前提到的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

1 个答案:

答案 0 :(得分:1)

根据回复here和与之关联的微软article,似乎情况是firebird odbc驱动程序与(大多数?)其他odbc驱动程序的运行方式不同,按设计

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

Firebird驱动程序的工作方式不同,通过一些示例

更容易解释

在下面的案例中,记录集只包含一条记录(因为clientid是主键,因而是唯一的),并假设其备注字段中的值为“bingo”。 更新方法将改为“等等”。表中所有行的备注字段值,其现有值为&#39; bingo&#39;。

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个列,并假设其备注字段中的值为&#39; bingo&#39;其姓氏领域的价值是琼斯&#39;。 更新方法将改为“等等”。表中所有行的备注字段值,其现有值具有&#39; bingo&#39;在他们的备忘录领域和琼斯&#39;在他们的姓氏领域。

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