Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Bazy danych [PostgreSQL] Auto-increment, jakiś pomysł?

10 Sie 2010 00:26 6418 6
  • Poziom 8  
    Witam,
    czy wie ktoś może, w jaki sposób zrobić "autoinkrementację" w postgres-ie?
    Wygenerowałam sobie bazę danych w Power Designer i chciałabym, aby id w odpowiednich tabelach było automatycznie uzupełniane.
    Może ktoś ma jakieś doświadczenie w tym temacie?
    Pozdrawiam
  • Poziom 40  
    W Postgresie jest pseudo - typ danych SERIAL i BIGSERIAL, który automatycznie tworzy pole typu liczbowego o odpowiedniej długości, NOT NULL z domyślną wartścią oraz sekwencję inkrementującą.
    Wystarczy tylko przy tworzeniu pola wybrać typ danych SERIAL, a Postgres resztę zrobi za Ciebie ;)
    Pamiętaj później, że do sekwencji też trzeba nadać uprawnienia do modyfikacji, bo np. INSERT nie będzie działał mimo że użytkownik ma nadane prawa do modyfikacji tabeli.
  • Poziom 8  
    Dzięki za odpowiedź,
    jestem raczej początkująca w postgresie. Mógłbyś mi więcej powiedzieć na temat tego uprawnienia do modyfikacji. Chodzi o to, że właśnie kombinowałam z nadaniem typu SERIAL, ale INSERT nie działa.
    Czy nadanie typu SERIAL już po stworzeniu bazy coś da?
  • Poziom 40  
    Tak naprawdę to zależy od narzędzia które używasz. Jeżeli poradzi sobie z przetłumaczeniem polecenia SERIAL na sekwencje poleceń, to być może wtedy się da.
    Ja używam pgAdmin III, i tam po utworzeniu tabeli nie ma możliwości z poziomu użytkownika zmodyfikowania istniejącego pola INTEGER na pole typu SERIAL - po prostu przestaje on być widoczny w typach do wyboru.

    Według dokumentacji: polecenie
    Code:

    CREATE TABLE tablename (
        colname SERIAL
    )

    jest tłumaczone na polecenie:
    Code:

    CREATE SEQUENCE tablename_colname_seq;
    CREATE TABLE tablename (
        colname integer DEFAULT nextval('tablename_colname_seq') NOT NULL
    );


    Czyli, mając już utworzoną tabelę z kolumną id typu INTEGER, możesz albo ją usunąć poleceniem DROP COLUMN a potem dodać poleceniem ADD COLUMN o typie serial (to doda kolumnę na koniec tabeli), albo zrobić to w ten sposób, nie zmieniając położenia kolumny:
    Code:

    CREATE SEQUENCE tbl_test_id_seq;

    ALTER TABLE tbl_test ALTER COLUMN id SET NOT NULL;
    ALTER TABLE tbl_test ALTER COLUMN id SET DEFAULT nextval('tbl_test_id_seq'::regclass);


    Tak czy inaczej najlepiej zawsze tworzyć te pola od początku o właściwym typie.
    A w sprawie uprawnień do modyfikacji: użytkownik dajmy na to usr_test musi mieć prawo do modyfikacji tabeli tbl_test ORAZ sekwencji tbl_test_id_seq. W pgAdmin robi się to tak:
    0. zakładamy że użytkownik jest już utworzony w "Zarejestrowane role"
    1. upewnij się że masz włączony widok użytkowników przy nadawaniu uprawnień (bodajże: Plik->Opcje->Preferencje, musi być zaznaczone "Wyświetlić uprawnienia użytkowników")
    2. Klikasz prawym przyciskiem na tabelę, właściwości->Uprawnienia, albo - zbiorowo - klikasz "Tabele" w drzewku i wybierasz "Kreator uprawnień", zaznaczasz tabele które chcesz zmodyfikować, w zakładce "Uprawnienia" wybierasz z listy użytkownika oraz uprawnienia i klikasz DODAJ.
    3. Z sekwencjami tak samo: klikasz w drzewku SEKWENCJE, kreator uprawnień, zaznaczasz wszystkie sekwencje i w uprawnieniach nadajesz najlepiej od razu prawa do ALL.
    Można też oczywiście kombinować z kodem SQL, ale po co skoro są kreatory ;)
  • Poziom 8  
    Dzięki za te instrukcje.
    Wykonałam wszystko tak jak pisałeś w tym drugim przypadku, czyli bez usuwania kolumny id.
    Nadałam uprawnienia użytkownikowi, tak jak podałeś.
    Mimo wszystko coś mi nie chce działać.
    Chcę wykonać insert np:
    Code:
    insert into public.osoba values(null,'Jan,'Kowalski')

    do tabeli np: osoba(id_osoba, imie, nazwisko)
    i niestety wywala mi następujący błąd:
    Code:
     null value in column "id_osoba" violates not-null constraint'. 

    Co w takiej sytuacji robię nie tak?
  • Pomocny post
    Poziom 40  
    A znasz angielski?? :)
    Komunikat mówi jasno co jest nie tak: wartość null w kolumnie id_osoba narusza ograniczenie nie-null :)
    Wartość pola ID jest ustawiona na NOT NULL, czyli nie akceptuje NULLi. Ty próbujesz wstawić "na siłę" wartość null więc masz błąd.
    Albo zrób tak:
    Code:

    insert into osoba values(DEFAULT ,'Jan',  'Kowalski')

    albo tak:
    Code:

    insert into osoba(imie, nazwisko) values('Jan',  'Kowalski')

    Ja preferuję drugi sposób, ponieważ jeżeli z czasem zmodyfikujesz ilość kolumn w tabeli lub zamienisz je miejscami, w pierwszym przypadku możesz otrzymać trudne do zdiagnozowania błędy. Jak "wyliczysz" wszystkie kolumny w odpowiedniej kolejności, to dodanie nowej ogranicza się do rozbudowania zapytania. I pamiętaj że w Postgresie niedobrze działają duże litery w nazwach kolumn, tzn. lepiej stosować tylko małe, gdyż nazwy z dużymi trzeba brać później w cudzysłowy. :)
  • Poziom 8  
    Przepraszam, ogólnie chodziło mi o sposób zapisu np inserta, ale nie wpadłam na pomysł wpisania danych z odpowiednimi wskazaniami:)
    Dzięki wielkie teraz już wszystko działa.
    Dziękuję również za wyrozumiałość.
    Pozdrawiam serdecznie
    Aśka