2013-07-23 70 views
0

我遷移我國從MSSQL的Delphi XE2應用程序(使用ADO組件),到PostgreSQL,使用UniDAC。PostgreSQL的串行(自動增量)與UniDac德爾福XE2

在數據庫中,有一些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; 

,異常是:

Exception

場 '身份證' 是TIntegerField,不TAutoIncrementField。

順便說一句,如果我使用的DBGrid編輯能力(準確地說,我使用ExpressQuantumGrid),要追加記錄到另一個表具有相同的結構,一切工作正常。

怎麼可能解決呢? 謝謝。

回答

1

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

2

大多數SQL兼容的方式是不是在所有登記在SQL查詢這個領域,讓它離開NULL,然後通過SQL Before Insert triggernull填寫到服務器上,以一個獨特的價值。

這是可以做到,如果UniDAC有插入查詢定製像TUpdateSQL了。

手動指定INSERT查詢(或INSERT-RETURNING,如果您以後需要該ID,出於任何原因:http://en.wikipedia.org/wiki/SQL_INSERT)是插入數據的最可控,高效和靈活的方式。


但是如果你做Append,不想寫SQL查詢這樣做,那麼你可以做post之前從服務器讀取的ID值。

1)聲明橫事務ID源:SQL SEQUENCE

2)查詢nextval()在做後,放入ID字段之前(你可以把它在TDataSet.BeforePost事件處理程序)


您還可以閱讀UniDAC文檔,並請在TUniTable幾個序列相關的屬性,對於您自動完成這一過程。 KeySequenceSequenceModehttp://www.devart.com/unidac/docs/pgsqlprov_article.htm#tuniquery_tunitable_tunistoredproc