2012-10-10 2 views
0

Я выполнил много поиска, но не смог найти ответ на мой запрос. То, что я прошу не может быть возможным, однако:Значение приращения по умолчанию в таблице postgresql

У меня есть ряд таблиц, но для упрощения будем считать, что у меня есть следующие

Статья ArticleID SERIAL

ArticlePageNumber ArticleID/ссылки статьи .articleId/ PageNumber Int

Это довольно очевидно, однако пояснительные данные 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, если нет) для записей с этой конкретной статьей.

Я бы предпочел сделать это в качестве ограничений и проверок внутри 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 (по умолчанию) при настройке последовательности.

хитрее - номер последовательности автоинкрементом страница, которая знает о статье

Вы можете использовать на строку триггер, который прослушивает экономит на статьи номера страницы таблицы и:

  • Проверяет, существует ли последовательность, специфичная для этого идентификатора статьи, и ее не существует
  • Назначает номер страницы из этой последовательности, если ее не существует

Код, приведенный ниже, прошел только тестирование света, но он должен проиллюстрировать мышление ...

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(); 
Смежные вопросы