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