2013-12-15 1 views
0

Мне нужно переконфигурировать одну таблицу с существующими данными, так что вам нужен совет/пример, как это сделать.PostgreSQL, перенастроить существующую таблицу, сменив первичный ключ на тип = serial

Мой любимый пример таблицы:

DROP TABLE IF EXISTS kalksad1; 

CREATE TABLE kalksad1(
kalk_id  int PRIMARY KEY, 
brkalk  integer, 
brred  integer, 
description text 
); 

INSERT INTO kalksad1 VALUES 
(12, 2, 5, 'text index 12 doc 2 row 5'), 
(26, 2, 1, 'text index 26 doc 2 row 1'), 
(30, 2, 2, 'text index 30 doc 2 row 2'), 
(32, 4, 1, 'text index 32 doc 4 row 1'), 
(36, 1, 1, 'text index 36 doc 1 row 1'), 
(37, 1, 2, 'text index 37 doc 1 row 2'), 
(38, 5, 1, 'text index 38 doc 5 row 1'), 
(39, 5, 2, 'text index 39 doc 5 row 2'), 
(42, 2, 3, 'text index 42 doc 2 row 3'), 
(43, 2, 4, 'text index 43 doc 2 row 4'), 
(46, 3, 1, 'text index 46 doc 3 row 1'), 
(47, 3, 2, 'text index 47 doc 3 row 2'); 

Простыми словами мне нужно несколько шагов.
1) Добавьте один новый столбец 'kalk_br' типа 'int'. (Я знаю, что нужно сделать),
2) Скопируйте содержимое всех ячеек «kalk_id» на «kalk_br». (Я не знаю, чтобы сделать это),
3) Изменить тип столбца для 'kalk_id' из 'int' в 'serial'. (Я не знаю, так как «kalk_id» является ПЕРВИЧНЫМ КЛЮЧОМ).

EDIT советами wildplasser в: 4) установить текущее значение для последовательного в MAX (kalk_id)

Возможно ли это сделать и как? Если нет, пожалуйста, любая идея решить это по-другому.

EDIT:
Это я пришел до сих пор:

/*1. rename kalk_id to kalk_br. 2. create a serial column kalk_id. 3. copy contents from kalk_br to kalk_id.*/ 

ALTER TABLE kalksad1 RENAME COLUMN kalk_id TO kalk_br; 
ALTER TABLE kalksad1 ADD COLUMN kalk_id serial; 
UPDATE kalksad1 SET kalk_id = kalk_br; 

Теперь остается:
1) Прекратить 'kalk_br' быть первичным ключом.
2) Установите 'kalk_id', который теперь является серийным, чтобы быть первичным ключом с самым высоким значением, обновленным как текущее значение.

+2

Как насчет переключения его вокруг? 1. переименуйте kalk_id в kalk_br. 2. Создайте последовательный столбец kalk_id. 3. Скопируйте содержимое с kalk_br на kalk_id. – Wolph

+0

Звучит неплохо. Можете ли вы привести пример кода, чтобы сделать это на показанной таблице? –

+1

+ добавить: '4) установить текущее значение для последовательного значения в MAX (kalk_id)' – wildplasser

ответ

3
CREATE SEQUENCE kalksad1_kalk_id_seq; 

ALTER TABLE kalksad1 
     ALTER COLUMN kalk_id SET DEFAULT nextval('kalksad1_kalk_id_seq') 
     ; 

ALTER SEQUENCE kalksad1_kalk_id_seq OWNED BY kalksad1.kalk_id; 

WITH mx AS (SELECT max(kalk_id) AS mx FROM kalksad1) 
SELECT setval('kalksad1_kalk_id_seq' , mx.mx) 
FROM mx 
     ; 

    -- Test it ... 
INSERT INTO kalksad1(brkalk, brred, description) VALUES (42, 666, 'Tralala'); 
SELECT * FROM kalksad1; 

Результат:

NOTICE: table "kalksad1" does not exist, skipping 
DROP TABLE 
CREATE TABLE 
INSERT 0 12 
CREATE SEQUENCE 
ALTER TABLE 
ALTER SEQUENCE 
setval 
-------- 
    47 
(1 row) 

INSERT 0 1 
kalk_id | brkalk | brred |  description   
---------+--------+-------+--------------------------- 
     12 |  2 |  5 | text index 12 doc 2 row 5 
     26 |  2 |  1 | text index 26 doc 2 row 1 
     30 |  2 |  2 | text index 30 doc 2 row 2 
     32 |  4 |  1 | text index 32 doc 4 row 1 
     36 |  1 |  1 | text index 36 doc 1 row 1 
     37 |  1 |  2 | text index 37 doc 1 row 2 
     38 |  5 |  1 | text index 38 doc 5 row 1 
     39 |  5 |  2 | text index 39 doc 5 row 2 
     42 |  2 |  3 | text index 42 doc 2 row 3 
     43 |  2 |  4 | text index 43 doc 2 row 4 
     46 |  3 |  1 | text index 46 doc 3 row 1 
     47 |  3 |  2 | text index 47 doc 3 row 2 
     48 |  42 | 666 | Tralala 
(13 rows) 
+0

Спасибо wildplasser. По моим немногим показаниям, которые, похоже, выполняют работу точно так, как ожидалось! –

+0

Конечно, это работает. Я тестирую его на реальных данных, которые огромны и проходят процедуру без каких-либо проблем. Спасибо за обновление ответа. –

Смежные вопросы