Oracle + Delphi, DataSet.Insert,表中有触发器,Post以后DataSet值与数据库不同步

rustle 2003-08-04 10:18:25
Oracle 8.1.7中有表A

A有字段ID

ID用触发器做的自增益

DataSet.Insert,DataSet.Fields[0].AsString := xxxxx;DataSet.Post后

DataSet.FieldByName('ID').AsInteger的值总是0

查阅Oracle Ole DB文档:DBPROP_SERVERDATAONINSERT

Server Data on Insert Property
If DBPROP_SERVERDATAONINSERT (Server Data on Insert) is set to TRUE using OraOLEDB, the consumer can obtain defaults, sequences, and triggered column values from newly inserted and updated rows, if the insert and update operations are made through the rowset.

Having DBPROP_SERVERDATAONINSERT set to TRUE may degrade performance for both insert and update executions using a rowset because OraOLEDB fetches row data from the database for the newly inserted and updated row. However, if DBPROP_SERVERDATAONINSERT is set to its default value of FALSE, only the explicitly provided values for insert and update operations get returned when column values are requested for those rows.

If the base table from which the rowset was created does not contain any defaults, sequences, or triggers, it is highly recommended that DBPROP_SERVERDATAONINSERT retain its default value of FALSE.

The DBPROP_SERVERDATAONINSERT property does not affect the performance of insert and update executions using the command object.

查阅MSDN
MSDN Home > MSDN Library > Data Access > Microsoft OLE DB > OLE DB Programmer's Reference > Part 5: Appendixes > Appendix C: OLE DB Properties > Properties (Alphabetical)
OLE DB Programmer's Reference

DBPROP_SERVERDATAONINSERT
Property group: Rowset

Property set: DBPROPSET_ROWSET

Column? N

Type: VT_BOOL

Typical R/W: R/W

Description: Server Data on Insert

Value Meaning
VARIANT_TRUE After an insert is transmitted to the server (when IRowsetChange::InsertRow is called in immediate mode or when IRowsetUpdate::Update is called for an inserted row in deferred update mode), the consumer can call IRowset::GetData to retrieve the actual values that appeared in the data store, including calculated columns and defaults not explicitly set in the call to IRowsetChange::InsertRow.
VARIANT_FALSE The provider does not retrieve values from the data store for newly inserted rows. The consumer can retrieve only data values explicitly set in the call to IRowsetChange::InsertRow or by calls to IRowsetChange::SetData for the hRow returned by InsertRow.

Consumers should be aware that setting DBPROP_SERVERDATAONINSERT is potentially expensive and may not be supported for certain types of rowsets.


如何使用这个属性?

试过DataSet.properties['DBPROP_SERVERDATAONINSERT'].value := true;报错...

请高手帮忙解决....

...全文
144 点赞 收藏 11
写回复
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
rustle 2003-08-06
虽然没有最好的答案

但是问题总算可以解决了

总结:
ADODataSet.RecordSet.Resync()可以刷新RecordSet对象中的数据,可以选择只更新当前纪录。具体调用参数可以参见MSDN中ADO文档的RecordSet对象的ReSync方法。参数已经作为常数定义在Adoint单元中。

在实际使用中,可以从TADODataSet继承新类,重写InternalPost方法,加一句RecordSet.Resync()就可以了。

这样就可以保证在post数据之后将RecordSet中的数据与oracle同步,这个方法对SQL Server的默认值等同样有效。对性能有影响(重新取回数据)但不大(只在Post数据的时候同步当前行)。
回复
rustle 2003-08-05
我这里现在有了一个解决的方法

就是DataSet.Recordset.Resync(adAffectCurrent, adResyncAllValues)

这样重载TADODataSet的DoAfterPost方法

也算可以解决这个问题了,不需要服务器端游标

recordSet的这个方法可以更新当前行,这个Resync似乎和DataSet里的Resync不一样,至少DataSet里的实现不是调用的RecordSet.Resync不一样,谁解释一下DataSet.Resync?

但是始终觉得不爽,那个参数到底怎么应用的?那个毕竟应该是最好的解决办法。

还有SQL Server中的identity应该是OLE DB内建支持了直接返回更新后的值,SQL Server中的默认值好像就不会这样,默认值怎么和DataSet同步呢?怎么做?
回复
CloneCenter 2003-08-05
dataset.Resync 需要服务器端的游标才可以被使用。
另外 Oracle 的触发器不能返回任何东西,建议使用一个存储过程返回需要的ID,否则使用 Refresh 刷新。
回复
firetoucher 2003-08-05
第34项 Fetch Backwards:=True

遗憾的是我没能找到例子中关键的属性DBPROP_SERVERDATAONINSERT,也就是Server Data On Insert对应的属性值,不知道她的IID是多少,希望能在声明文件中查找到(我这里没有啊)
Consumers should be aware that setting DBPROP_SERVERDATAONINSERT is potentially expensive and may not be supported for certain types of rowsets
回复
firetoucher 2003-08-05
1 Oracle没有用过,但是在sql server里没有问题的,直接就可以返回identity
2 你试试将properties中的
第0项 IAccessor:=True
第1项 IChapteredRowset:=True
第10项 IRowsetChange:=True
第13项 IRowsetIdentity:=True
回复
rustle 2003-08-05
大家没遇到也可以帮我一起研究研究阿...
回复
rustle 2003-08-05
1 你可以调用dataset.refresh得到(Resync也可以,但是borland建议应该在程序中使用refresh而不是Resync)——太慢了吧

2 properties是只读属性,不能赋值——properties是只读属性,但Properties['xxx'].value是可以赋值的,只不过此properties不是彼properties啦...

3 对于序列号和流水号等的插入,由于并发性比较强,可以用存储过程,返回插入后的id,或者错误码(<0)的办法——具体怎么做?自增益已经做到了,要怎么使DataSet获得插入后的值?...

望赐教!
回复
firetoucher 2003-08-05
1 你可以调用dataset.refresh得到(Resync也可以,但是borland建议应该在程序中使用refresh而不是Resync)
2 properties是只读属性,不能赋值
3 对于序列号和流水号等的插入,由于并发性比较强,可以用存储过程,返回插入后的id,或者错误码(<0)的办法
回复
rustle 2003-08-05
SQL Server的OLE DB驱动也有这个属性的,怎么应用应该是个通用的问题。

这个似乎不是ADO的recordset对象里的属性,应该是OLE DB驱动里的RowSet对象的属性


怎么用没搞明白

大家可以帮我看看这篇文章,里面有C++的用法...

http://support.microsoft.com/default.aspx?scid=http://support.microsoft.com:80/support/kb/articles/q219/0/29.asp&NoWebContent=1

相关MSDN资料:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/oledb/htm/oledbstartpage1.asp
回复
Eastunfail 2003-08-05
也没用过Oracle
回复
flyingkiller 2003-08-05
Up
没用过Oracle的说。
回复
发动态
发帖子
数据库相关
创建于2007-08-02

2440

社区成员

Delphi 数据库相关
申请成为版主
社区公告
暂无公告