2012-10-10 35 views
0

我已經進行了很多搜索,但無法找到我的查詢的答案。什麼我問可能無法但是:postgresql表中的默認遞增值

我有一系列的表,但爲了簡化我們假設我有以下

文章 條款ArticleID SERIAL

ArticlePageNumber 條款ArticleID/引用文章的.articleId/ PAGENUMBER詮釋

這是相當自我解釋然而數據thatwould是可接受的。將

Article 
------- 
articleiId 
1 
2 

ArticlePageNumber 
----------------- 
articleiId pageNumber 
1   1 
1   2 
1   3 
1   4 
1   5 
1   6 
2   1 
2   3 
2   5 
2   2 
2   4 

一個不可接受的表是ArticlePageNumber

ArticlePageNumber 
----------------- 
articleiId pageNumber 
1   1 
1   1 
1   2 
1   3 
1   4 
1   5 
2   1 
2   3 
2   5 
2   4 

我想的默認值ArticlePageNumber.pageNumber遞增類似於串行確實不過下一個值將是依賴於前值的方式(如果沒有,則爲1)用於特定articleId的條目。

我寧願這樣做,因爲SQL中的約束和檢查,而不是代碼,但我猜測它可能是不可能的。

+1

可能類似於http://stackoverflow.com/questions/12746106/how-to-create-multiple-sequences-in-one-table/12746929 – jcern

+0

@jcern於審查其他問題,你說的很對有相當多的相似性,並有一些可能解決我的問題的建議。謝謝。 – Peter

回答

2

,你需要的行爲是不可能的,但是是棘手:

容易實現 - 一個頁面的順序,不知道什麼文章它連接到

首先,創建序列對於頁碼如下:

CREATE SEQUENCE page_number_sequence; 

如果需要調整分配大小,開始等look here

然後:定義「article_page_number」表時,定義PAGENUMBER領域如下:

# omitted boilerplate 
pageNumber integer not null default nextval('page_number_sequence') 

,將自動填寫爲您的頁碼以遞增的方式。如果您不想要「gappy」序號,請在設置序列時將增量設置爲1(默認值)並將緩存設置爲1(默認值)。

棘手 - 這是瞭解文章的

你可以使用每行觸發偵聽節省了文章頁面數表和自動增量的頁面順序:

  • 檢查是否存在特定於該文章ID的序列,並創建該序列不存在
  • 如果不存在,則從該序列分配一個頁碼

下面的代碼只經過了光線測試,但它應該說明這個想法...

CREATE TABLE IF NOT EXISTS article (
    articleId SERIAL PRIMARY KEY 
); 

CREATE TABLE IF NOT EXISTS article_page_number (
    articleId INTEGER NOT NULL, 
    pageNumber INTEGER NOT NULL, 
    CONSTRAINT article_fk FOREIGN KEY (articleId) 
     REFERENCES article (articleId) 
); 

CREATE OR REPLACE FUNCTION page_number_trg() 
    RETURNS trigger AS 
$BODY$ DECLARE 
    seqname VARCHAR(60):= NULL; 
BEGIN 
    IF (TG_OP = 'INSERT') THEN 
    BEGIN 
     seqname:= 'pageno_seq_'||NEW.articleId; 
     IF NOT EXISTS (SELECT 0 FROM pg_class where relname = seqname) THEN 
     EXECUTE 'CREATE SEQUENCE '||seqname; 
     END IF; 
     IF NEW.pageNumber IS NULL THEN 
     NEW.pageNumber := nextval(seqname); 
     END IF; 
    END; 
    END IF; 
    IF TG_OP = 'DELETE' THEN RETURN OLD; ELSE RETURN NEW; END IF; 
END 
; $BODY$ 
LANGUAGE plpgsql; 

CREATE TRIGGER page_number_trg 
BEFORE INSERT ON article_page_number 
FOR EACH ROW 
EXECUTE PROCEDURE page_number_trg();