crossplatform.ru

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

 
Ответить в данную темуНачать новую тему
> Как работать с таблицей, содержащей уникальный набор значений типа double?
Steklova Olga
  опции профиля:
сообщение 11.6.2013, 10:18
Сообщение #1


Участник
**

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

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




Репутация:   4  


Всем привет :)
В таблице БД FireBird надо хранить массивы значений F_FR для разных объектов (TO_F_OBJ_NMB - номер объекта).
Значения содержат 1..6 цифр в целой части, 2 цифры в дробной части, значения положительные.
Для конкретного объекта массив F_FR не должен содержать повторяющиеся значения.


Таблица создана так
--TABLE T_OBJ_FR может содержать 0...100 значений F_FR для каждого TO_F_OBJ_NMB
CREATE TABLE T_OBJ_FR (
    F_RECORD_NMB     INTEGER NOT NULL, --генератор
    TO_F_OBJ_NMB     INTEGER NOT NULL, --внешний ключ
    F_FR             DOUBLE PRECISION NOT NULL
);
ALTER TABLE T_OBJ_FR ADD CONSTRAINT PK_T_OBJ_FR PRIMARY KEY (F_RECORD_NMB);

Для корректировки таблицы T_OBJ_FR использую диалог,
в котором для корректировки поля F_FR использую doubleSpinBox.

Мне непонятно вот что:
1) можно ли создать уникальный ключ, содержащий поле типа DOUBLE PRECISION? (например, создать уникальный ключ (TO_F_OBJ_NMB, F_FR))
2) если не создавать уникальный ключ, то как проверить, есть ли уже в таблице только что введенное оператором в doubleSpinBox значение F_FR? (как написать SELECT?)
3) не лучше ли будет описать поле F_FR как NUMERIC(8,2), а не DOUBLE PRECISION?
4) можно ввести значение типа NUMERIC(8,2) с помощью doubleSpinBox?
5) можно создать уникальный ключ, содержащий поле типа NUMERIC?

Сообщение отредактировал Steklova Olga - 13.6.2013, 9:15
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 11.6.2013, 11:59
Сообщение #2


фрилансер
******

Группа: Участник
Сообщений: 2941
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

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




Репутация:   34  


варианты удобного, на мой взгляд, ключа:

1) текстовый с фиксированным форматом "000000.00"

2) целый (10 знаков)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
alex977
  опции профиля:
сообщение 11.6.2013, 17:05
Сообщение #3


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

Группа: Участник
Сообщений: 310
Регистрация: 19.6.2008
Из: Россия, МО, г.Мытищи
Пользователь №: 206

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




Репутация:   8  


Цитата(Steklova Olga @ 11.6.2013, 11:18) *
F_FR             DOUBLE PRECISION NOT NULL


Возможно нужно добавить "UNIQUE"

Цитата
3.Уникальный ключ

Уникальный ключ - дополнительная возможность ограничения значений записей таблицы с целью профилактики занесения в нее двух и более записей, имеющих одинаковое значение указанного столбца (столбцов). В отличие от PRIMARY KEY количество уникальных ключей в таблице неограничено (точнее, ограничено максимальной комбинаторной суммой вариантов комбинации имен доменов, входящих в таблицу). Уникальный ключ также называется «альтернативным», и чаще всего предназначен не для однозначной идентификации столбца, как Первичный ключ, а для указания столбца, который позволяет осуществить дополнительную идентификацию строки. Например - номер паспорта, код ИНН, номер пенсионной страховки, и т.д.

Указание NOT NULL для UNIQUE, начиная с Firebird 1.5, не является обязательным. При этом уникальный индекс, который будет контролировать данное ограничение UNIQUE, может содержать NULL. Такой индекс невозможно создать командой CREATE INDEX.

Уникальный ключ может быть объявлен как и при описании домена:

CREATE TABLE MY_TABLE(
......
FIELD1 INTEGER NOT NULL UNIQUE,
.....
);
так и при описании таблицы (рекомендуемый вариант, с указанием имени constraint)

CREATE TABLE MY_TABLE(
....
FIELD1 INTEGER NOT NULL,
FIELD2 INTEGER NOT NULL,
....
CONSTRAINT UNQ_MY_TABLE_1 UNIQUE(FIELD1, FIELD2),
....
);
При создании уникального ключа для версий Firebird ниже 1.5, столбец или домен должен содержать дополнительное ограничение ссылочной целостности NOT NULL. Подробнее см. CREATE DOMAIN


источник: http://www.firebirdsql.su/doku.php?id=constraint
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.6.2013, 7:32
Сообщение #4


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

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

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




Репутация:   94  


Steklova Olga, Уникальность ключа не зависит от типа данных, задаётся она как описал alex977.
Цитата(Steklova Olga @ 11.6.2013, 12:18) *
4) можно ввести значение типа NUMERIC(8,2) с помощью doubleSpinBox?
В Qt (и не только) с этим проблема. Qt не может обрабатывать все типы СУБД, т.к. в Си++ свои типы. Поэтому работа идёт со строкой, которую Qt пытается ограничить до заданных пределов при записи в БД, но не в момент редактирования.
Лучше для подобных типов сразу писать делегат, который не даст пользователю выйти за рамки дозволенного.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 13.6.2013, 11:18
Сообщение #5


Участник
**

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

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




Репутация:   4  


Litkevich Yuriy, большое спасибо за ответ :)

Цитата(Алексей1153 @ 11.6.2013, 11:59) *
варианты удобного, на мой взгляд, ключа:
1) текстовый с фиксированным форматом "000000.00"
2) целый (10 знаков)
это неудобно

Добавила уникальный ключ
ALTER TABLE T_OBJ_FR ADD CONSTRAINT UK_T_OBJ_FR__OF UNIQUE (TO_F_OBJ_NMB, F_FR);

Работает. Только, чтобы все было корректно, надо при работе с полем F_FR всегда использовать одинаковое кол-во цифр в дробной части (в моем случае - две).
Иначе может получиться вот что.
Например:
в tableView для поля F_FR укажем отображать 2 цифры в дробной части,
для dblSpinBox для корректировки значения F_FR укажем setDecimals(2).
Если оператор выполнит скрипт заполнения таблицы, указав (по ошибке) для значений F_FR не 2, а 3 цифры в дробной части,
INSERT INTO T_OBJ_FR (TO_F_OBJ_NMB, F_FR) VALUES ( 1, 1.11);
INSERT INTO T_OBJ_FR (TO_F_OBJ_NMB, F_FR) VALUES ( 1, 1.114);
INSERT INTO T_OBJ_FR (TO_F_OBJ_NMB, F_FR) VALUES ( 1, 1.117);
то в tableView он увидит значения 1.11, 1.11, 1.12, по внешнему виду нарушающие уникальность,
к тому же оператор сможет добавить в эту таблицу значение F_FR, равное 1.12.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 13.6.2013, 16:47
Сообщение #6


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

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

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




Репутация:   94  


Цитата(Steklova Olga @ 13.6.2013, 13:18) *
Если оператор выполнит скрипт заполнения таблицы
ну нужно, чтобы ПО не предоставляло возможности выполнять скрипт непосредственно, а только через интерфейс программы (которая будет всё проверять).


а как происходит вставка таких данных, если поле имеет тип с двумя знаками после запятой?
Ошибка не возникает?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Steklova Olga
  опции профиля:
сообщение 14.6.2013, 9:43
Сообщение #7


Участник
**

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

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




Репутация:   4  


Цитата(Litkevich Yuriy @ 13.6.2013, 16:47) *
нужно, чтобы ПО не предоставляло возможности выполнять скрипт непосредственно, а только через интерфейс программы (которая будет всё проверять)
Обычно создаю БД, запуская серию скриптов, в одном из которых заполняю словари и постоянные таблицы. Мне это удобно.

Цитата(Litkevich Yuriy @ 13.6.2013, 16:47) *
а как происходит вставка таких данных, если поле имеет тип с двумя знаками после запятой?
Ошибка не возникает?
Так у меня-то поле описано так:
F_FR DOUBLE PRECISION NOT NULL
Не стала его переделывать на поле с фиксированной запятой типа NUMERIC или DECIMAL,
потому что я не понимаю всех тонкостей этих типов, мне сложно написать для них делегат.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 15.6.2013, 14:39
Сообщение #8


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

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

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




Репутация:   94  


Цитата(Steklova Olga @ 14.6.2013, 11:43) *
Не стала его переделывать на поле с фиксированной запятой типа NUMERIC или DECIMAL
тонкостей у этих типов нет ни каких, лучше всё-таки защитить данные на уровне БД
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 28.11.2024, 20:08