crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> PK в PostgreSQL
Rocky
  опции профиля:
сообщение 4.3.2010, 17:09
Сообщение #1


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


Всем привет!

Пытаюсь создать таблицу в PostgreSQL и одно из полей сделать PK.
Пробую так:
bRetVal = oQuery.exec(QString("CREATE TABLE tab (ID BIGSERIAL, "
":Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3, "
"PRIMARY KEY (ID));"));
//bRetVal == true

bRetVal = oQuery.prepare(QString("INSERT INTO tab VALUES("
        ":Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3, "
        ");"));
//bRetVal == true


//Потом
oQuery.bindValue(":Pict_ID_1_1", 1);
oQuery.bindValue(":Pict_ID_2_1", 2);
oQuery.bindValue(":Pict_ID_3_1", 3);

bRetVal =oQuery.exec();
//bRetVal == false


Пробовал через sequence:
bRetVal = oQuery.exec(QString("CREATE SEQUENCE tab_sq START WITH 1"));
//bRetVal == true

bRetVal = oQuery.exec(QString("CREATE TABLE BananasGoBahamas (ID DEFAULT NOT NULL nextval('tab_sq') PRIMARY KEY, "
        "Pict_ID_1_1 INTEGER, Pict_ID_1_2 INTEGER, Pict_ID_1_3 INTEGER);"));
//bRetVal == true

bRetVal = oQuery.prepare(QString("INSERT INTO tab VALUES(:ID, "
        ":Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3, "
        ");"));
//bRetVal == true


//Потом
oQuery.bindValue(":ID", "tab_sq.nextval");
oQuery.bindValue(":Pict_ID_1_1", 1);
oQuery.bindValue(":Pict_ID_2_1", 2);
oQuery.bindValue(":Pict_ID_3_1", 3);

bRetVal =oQuery.exec();
//bRetVal == false


Как я понял, в постгрессе нету AUTOINCREMENT... Вобщем, никак не работает... (( Кто-нибудь знает в чем может быть проблема?

Спасибо)

Сообщение отредактировал Rocky - 4.3.2010, 17:10
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 4.3.2010, 17:11
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Rocky @ 4.3.2010, 17:09) *
Как я понял, в постгрессе нету AUTOINCREMENT... Вобщем, никак не работает... (( Кто-нибудь знает в чем может быть проблема?

тогда наверное придётся тригер на вставку делать, как это было в InterBase

Сообщение отредактировал DEADHUNT - 4.3.2010, 17:12
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.3.2010, 17:21
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Есть в PostgreSQL понятие "Генератор"?
Если есть, то тогда точно, как в InterBase/Firebird - Генератор+Тригер
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 4.3.2010, 17:26
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 4.3.2010, 17:21) *
Если есть, то тогда точно, как в InterBase/Firebird - Генератор+Тригер

можно и без генератора обойтись, взять максимум по PK прибавить 1 и это будет новый PK.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rocky
  опции профиля:
сообщение 4.3.2010, 17:42
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


А можно маленький примерчик плиз? Я просто вот только-только взялся по-серьезному за базы данных =)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 4.3.2010, 17:43
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Цитата(DEADHUNT @ 4.3.2010, 17:11) *
Как я понял, в постгрессе нету AUTOINCREMENT

Неправильно понял, точнее наделал ошибок и сделал неправильный вывод.
В PostgreSQL автоинкрементное поле осуществляется через тип SERIAL/BIGSERIAL (по сути это последовательность + "триггер").

В общем, по порядку:
1.
bRetVal = oQuery.exec(QString("CREATE TABLE tab (ID BIGSERIAL, "
":Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3, "
"PRIMARY KEY (ID));"));

Я не понял эту конструкцию, так что создалась таблица?

2.
bRetVal = oQuery.prepare(QString("INSERT INTO tab VALUES(" 
        ":Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3, "
        ");"));

Тут запрос неправильный, т.к. в таблице tab 4 поля, а не 3. Текст должен быть примерно такой:
"INSERT INTO tab(Pict_ID_1_1, Pict_ID_1_2, Pict_ID_1_3) VALUES(:Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3);"

3.
oQuery.bindValue(":ID", "tab_sq.nextval");

Тут ты пытаешься в 1-е поле с числовым типом записать текстовую строку "tab_sq.nextval" (тем более в описании таблцы уже задан автоикремент).

4.
oQuery.bindValue(":Pict_ID_1_1", 1);
oQuery.bindValue(":Pict_ID_2_1", 2);
oQuery.bindValue(":Pict_ID_3_1", 3);

А в подготовленном запросе писал :Pict_ID_1_1, :Pict_ID_1_2, :Pict_ID_1_3

Вот попробуй так:
bRetVal = oQuery.exec(QString("CREATE TABLE tab (
                                              " ID BIGSERIAL,"
                                              " Pict_ID_1_1 INTEGER,"
                                              " Pict_ID_1_2 INTEGER,"
                                              " Pict_ID_1_3 INTEGER,"
                                              " CONSTRAINT tab_PK PRIMARY KEY (ID));"
                                              )
                                  );

bRetVal = oQuery.prepare("INSERT INTO tab(Pict_ID_1_1, Pict_ID_1_2, Pict_ID_1_3) VALUES(:Pict_1, :Pict_2, :Pict__3);");

//Потом
oQuery.bindValue(":Pict_1", 1);
oQuery.bindValue(":Pict_2", 2);
oQuery.bindValue(":Pict_3", 3);

bRetVal =oQuery.exec();


Сообщение отредактировал MoPDoBoPoT - 4.3.2010, 17:44
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rocky
  опции профиля:
сообщение 4.3.2010, 18:17
Сообщение #7


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


Ого )

1. AUTOINCREMENT я имел ввиду именно ключевое слово, SERIAL я потом прочитал что это аналог этому AUTOINCREMENT... Ну да, таблица создалась )) А что в ней не так?

2. Блин, понял ( Я чето решил что из-за явного указания имен полей модуль QtSql при формировании запроса сам подставит по полям что куда нужно..

3. Упс, тут описался, на самом деле было так (просто за 3 часа уже устал туда-сюда все менять, вот не то и вписал под конец)
bRetVal = oQuery.exec(QString("CREATE TABLE BananasGoBahamas (ID INTEGER NOT NULL DEFAULT 
nextval('tab_sq') PRIMARY KEY,........


4. там все ок, просто у меня 32 поля, я все тут не стал писать (


Уря, заработало!!!

Тока в консоли пишет:
Цитата
NOTICE: CREATE TABLE will create implicit sequence "tab_id_seq" for serial column "tab.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "tab_pk" for table "tab"

Это ничего страшного?

Сообщение отредактировал Rocky - 4.3.2010, 18:19
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
MoPDoBoPoT
  опции профиля:
сообщение 4.3.2010, 18:27
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 172
Регистрация: 7.5.2009
Из: Москва
Пользователь №: 738

Спасибо сказали: 44 раз(а)




Репутация:   9  


Цитата(Rocky @ 4.3.2010, 18:17) *
Это ничего страшного?

Это просто уведомление о том, что неявно создаются объекты/конструкции (последовательность и индекс).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Rocky
  опции профиля:
сообщение 4.3.2010, 18:42
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 530
Регистрация: 22.12.2008
Из: Санкт-Петербург
Пользователь №: 463

Спасибо сказали: 22 раз(а)




Репутация:   7  


А еще вопросик можно? А при указании имен столбцов в QSqlQuery::prepare важен порядок имен столбцов? Т.е. он должен быть такой же как и при создании таблицы, или без разницы?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 4.3.2010, 18:50
Сообщение #10


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9668
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 4.3.2010, 20:26) *
PK прибавить 1 и это будет новый PK.
нет нельзя, т.к. могут существовать разные транзакции и значение может быть не уникальным. А генератор гарантирует уникальность
Во всяком случае в firebird/interbase, т.к. они версионники, а не блокировочники (как, например, MySQL)

Цитата(Rocky @ 4.3.2010, 21:42) *
в QSqlQuery::prepare важен порядок имен столбцов? Т.е. он должен быть такой же как и при создании таблицы, или без разницы?
зависит от типа подстановки, позиционная/именованная.
Для последней без разницы, подробности см. в описании класса
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 26.10.2021, 23:36