首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi XE2上的PostgreSQL串行(自动递增)和UniDac

Delphi XE2上的PostgreSQL串行(自动递增)和UniDac
EN

Stack Overflow用户
提问于 2013-07-23 20:55:51
回答 2查看 1.5K关注 0票数 1

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

在数据库中,有一些serial类型字段(自动递增)。当我追加记录时,我没有将任何数据放到这个自动增量字段中。通常,对于MSSQL/ADO,它会自动工作,但现在我有一个例外。

代码:

代码语言:javascript
复制
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),将记录附加到另一个具有相同结构的表中,一切工作正常。

如何解决这个问题呢?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-24 20:36:38

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

2) UniDAC支持按顺序自动填写字段。为此,您应该按如下方式设置TUniQuery.KeyFields和TUniQuery.SpecificOptions.Values‘’KeySequence‘属性:

代码语言:javascript
复制
  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

票数 2
EN

Stack Overflow用户

发布于 2013-07-23 21:36:13

大多数兼容SQL的方法是根本不在SQL query中登记这个字段,让它离开NULL,然后在服务器上通过SQL Before Insert trigger将它从null填充到一个唯一的值。

如果像TUpdateSQL一样,UniDAC具有插入查询自定义,则可以做到这一点。

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

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

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

  • http://doc.artofweb.ru/doc/Последовательности_в_PostgreSQL
  • http://www.neilconway.org/docs/sequences/
  • http://www.postgresql.org/docs/9.1/static/functions-sequence.html
  • http://www.postgresql.org/docs/8.1/static/sql-createsequence.html

2) post前查询nextval(),放入ID字段(可以在TDataSet.BeforePost事件处理器中实现)

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17810795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档