在Delphi XE2上使用UniDac进行PostgreSQL串行(自动增量)

时间:2013-07-23 12:55:51

标签: delphi postgresql delphi-xe2 devart unidac

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

在数据库中,有一些serial类型字段(自动增量)。当我追加记录时,我没有将任何数据添加到此自动增量字段中。 Formely,使用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;

例外是:

Exception

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

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

怎么可能解决它? 感谢。

2 个答案:

答案 0 :(得分:2)

大多数符合SQL的方法都不是在SQL查询中登记此字段,而是让它离开NULL然后通过SQL Before Insert triggernull填写到服务器上独特的价值。

如果UniDAC具有TUpdateSQL之类的插入查询自定义,则可以执行此操作。

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


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

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

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


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

答案 1 :(得分: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何时使用序列填写字段:on call Append / Insert或Post。

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