1

我正在使用 UniDAC 将我们的 Delphi XE2 应用程序从 MSSQL(使用 ADO 组件)迁移到 PostgreSQL。

在数据库中,有一些serial类型字段(自动增量)。当我追加记录时,我没有将任何数据放入此自动增量字段。以前,使用 MSSQL/ADO 它会自动工作,但现在我有一个例外。

编码:

aqrMsgs.Append;
aqrMsgsUser_From.AsInteger := UserId;
aqrMsgsUser_To.AsString := UserIds[I];
aqrMsgsSubject.AsString := Trim (edtSubject.Text);
aqrMsgsContents.AsString := mmoContents.Text;
aqrMsgsIsDone.AsBoolean := False;
aqrMsgs.Post;

例外是:

例外

字段 'id' 是TIntegerField,而不是 TAutoIncrementField。

顺便说一句,如果我使用 DBGrid 编辑功能(确切地说,我使用的是 ExpressQuantumGrid),将记录附加到具有相同结构的另一个表中,一切正常。

怎么可能解决?谢谢。

4

2 回答 2

2

大多数符合 SQL 的方法是根本不在 SQL 查询中登记此字段,让它离开NULL,然后通过SQL Before Insert triggerfrom将其填充到服务器上null的唯一值。

如果UniDAC有插入查询自定义,则可以这样做TUpdateSQL

手动指定INSERT查询(或者INSERT-RETURNING如果您以后出于任何原因需要 ID:http ://en.wikipedia.org/wiki/SQL_INSERT )是插入数据的最可控、最有效和最灵活的方式。


但是,如果您这样做Append并且不想为此编写 SQL 查询,那么您可以在执行之前从服务器读取 ID 值post

1)声明跨事务ID来源:SQL SEQUENCE

2)nextval()在发布之前查询并将其放入ID字段(您可以在TDataSet.BeforePost事件处理程序中进行)


您还可以阅读 UniDAC 文档并查看一些与序列相关的属性,TUniTable这些属性可以为您自动执行此过程。 在http://www.devart.com/unidac/docs/pgsqlprov_article.htm#tuniquery_tunable_tunistoredprocKeySequence _SequenceMode

于 2013-07-23T13:36:12.970 回答
2

1) 当你创建一个序列类型的字段时,PostgreSQL 服务器会自动创建一个序列,这个序列中的值将作为该字段的默认值。如果插入新记录时未设置序列字段,则服务器从序列中获取一个值。但是如果你为序列字段设置了一个值,服务器会插入这个值。由于序列对您插入到序列字段的值一无所知,因此在进一步插入记录时(使用序列时),如果序列字段是使用唯一约束创建的,则可能会发生“重复键值”错误. 如果您不手动设置此字段的值,则不会遇到此问题。

2) UniDAC 可以使用序列自动填充字段。为此,您应该如下设置 TUniQuery.KeyFields 和 TUniQuery.SpecificOptions.Values['KeySequence'] 属性:

  UniQuery1.KeyFields := 'id'; 
  UniQuery1.SpecificOptions.Values['KeySequence'] := 'test1_id_seq';

此外,使用 TUniQuery.SpecificOptions.Values['SequenceMode'] 属性,您可以指定 UniDAC 何时使用序列填充字段:调用 Append/Insert 或 Post。

您可以在此处找到有关上述属性的详细信息:http: //www.devart.com/unidac/docs/pgsqlprov_article.htm

于 2013-07-24T12:36:37.860 回答