Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как проверит через SQL уникальность записи 
:(
    Опции темы
User
Дата 29.12.2004, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 5.11.2004

Репутация: нет
Всего: нет



Вопрос такого плана. Я ни как не пойму как написать запрос
в query2 при добавлении нового поля на уникальность записи.
Использую:
Edit1 - строка ввода текста
Query1 - добавление новой записи в dxDBGrid
Query2 - проверка на уникальность

Query1.Close;
..............
Query1.Open;
А как проверить на уникальность непойму. Помогите. Было бы неплохо если приведете пример smile
PM MAIL WWW   Вверх
User
Дата 29.12.2004, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 213
Регистрация: 5.11.2004

Репутация: нет
Всего: нет



Да уточню. Проверять имеющиеся записи необходимо в dxDBGrid на уникальность при добавлении новой запись в Edit1
PM MAIL WWW   Вверх
Bes
Дата 29.12.2004, 13:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



"...при добавлении нового поля на уникальность записи..."

Подожди, подожди.... ерунда какая-то...
Ты добавляешь поле или запись все-таки?
Т.е. ты модифицируешь структуру таблицы или просто добавляешь данные?
Далее что значит уникальность? т.е. какие поля должны быть уникальны?
Скажем уникальны ли записи
a, b
b,a
a,a
b,b

или только
a, b
b, a.
Вообще это очень важно, т.к. может решаться на уровне проектирования базы данных либо проверяться запросом...
УТОЧНЯЙ. с примером :-)
PM MAIL   Вверх
Vit
Дата 29.12.2004, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: 14
Всего: 207



1. Уникальность лучше всего обеспечивается назначением ключа по уникальному полю


2. вот код который проверяет на уникальность

Код

if query1.locate('FieldName','FieldValue',[]) then
 запись есть
else
 записи нет





--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Bes
Дата 29.12.2004, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



2Vit: да, но реч может идти не об уникальности значения в нек. поле т.е. да, т.о. действительно лучше это решить при построении базы, однако если говорить об уникальности записи т.е. допустима ситуация
a, b
b,a
a,a
b,b
то стоит говорить о запросе типа

insert into tab1 (p1,p2) values (b,c)
where not exists (select * from tab1 where p1=b and p2=c)

так?
PM MAIL   Вверх
Dimich
Дата 29.12.2004, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



Насколько я знаю,
Цитата(Bes @ 29.12.2004, 16:19)
insert into tab1 (p1,p2) values (b,c)
where not exists (select * from tab1 where p1=b and p2=c)

такой синтаксис не прокатит.
Думаю, сперва нужно проверить selectом возможность вставки, а уже потом делать insert

Но такой вариант (select а затем insert) не очень для многопользовательских баз. Уж куда лучше правильно продумать структуру БД, чтобы иметь возможность использовать уникальные ключи и ограничения
--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
Bes
Дата 30.12.2004, 07:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



2Dimich: прокатит!!! Д6 скул2000 да и в акцессе тоже работает.
такая конструкция допустима с точки зрения самого синтаксиса и является пожалуй самой надежной проверкой, т.к. если как ты говоришь сначала делать селект, а потом инсерт то для многопользовательского режима в момент между селектом и инсертом др. пользователь может вставить такую же запись и получиться дубликат.
А в конструкции такой ничего криминального нет. такой синтаксис прокатит - проверено на практике :-)
С уважением Be§.
PM MAIL   Вверх
Dimich
Дата 30.12.2004, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



Даже самому интересно стало попробовать (просто перерыл горы инфы по SQL, но так и не нашел ничего про Insert с условием)! Вот открываю Access 2000 (предупреждаю - я в нем дремучий), создаю табличку MYTABLE с числовыми полями f1,f2,f3 и пытаюсь писать такой Insert:
Код

Private Sub Кнопка0_Click()
 Dim SQL As String
 SQL = "insert into mytable (f1,f2,f3) values (1,1,1) where f1 not exist (select f1 from mytable);"
 DoCmd.RunSQL SQL
End Sub

и ничего! Т.е. ошибка 3137 "пропущен символ (;) в конце инструкции SQL
т.е. я понимаю, что все после и включительно "where" неправильно? Ничего не понимаю! Говорите, что можно? Покажите пожалуйста - КАК?

З.Ы. Это мне не горит, просто интересно для собственного развития!
--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
Bes
Дата 30.12.2004, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



Дак там в моем примере написано не
...where f1 not exist...
а
...where not exist...
т.е. вся конструкция переводится так:

insert into tab1 (p1,p2) values (b,c)
where not exists (select * from tab1 where p1=b and p2=c)

вставить в Таб1 в поля п1,п2 значения б и ц
где не существует следующей записи:
выбрать всё из таблицы Таб1 где п1=б а п2=ц

т.е. естесвенно, что имя поля м/у словами where и exists (или not exists) ни к чему - следовательно она ругается на синтаксис, а exists такое же условие выборки как <>,= или IN и пр. только условием является запрос - очень полезная штука.

приемущество такой структуры в том, что она выполняется одним запросом и может либо выполниться, либо нет.

Кстати, если вас так смущает наличие вместе insert и select то вот еще одна полезная конструкция

insert into tab1 (select * from tab2 where a>10) знаете, нет такую?

Да, еще: с акцессом я общаюсь через Д6 так что про (;) я забыл да и не знал. :-)

Это сообщение отредактировал(а) Bes - 30.12.2004, 11:46
PM MAIL   Вверх
Dimich
Дата 30.12.2004, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



Нет, пробовал я и так и так, ничего не получается!
Вот родилась мысля, а не сделать ли так (вариант для Oracle):
Код

insert into mytable (f1,f2,f3)
(select :p1, :p2, :p3 from dual where :p1 not in (select :p1 from mytable))

--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
Bes
Дата 30.12.2004, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



2Dimich:
Вот, работающий код из моей работы для Access97 из Д6 через БДЕ служит уже год.

UpdateLitNomStringNew:='update prod set nom = :nom where key = :key and not exists (select * from prod where nom = :onom and data = :odata and stch = :ostch)';

QueryChek.Active:=false;
QueryChek.SQL.Text:=UpdateLitNomStringNew;
QueryChek.Params[0].AsInteger:=maxS+1;
QueryChek.Params[1].AsInteger:=Key;
QueryChek.Params[2].AsInteger:=maxS+1;
DateTimeToString(Sdt,'dd.mm.yyyy',T);
QueryChek.Params[3].AsDateTime:=StrToDate(sdt);
QueryChek.Params[4].AsBoolean:=true;
QueryChek.ExecSQL;

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

Да, в этом ТВОЕМ запросе
insert into mytable (f1,f2,f3)
(select smile1, smile2, smile3 from dual where smile1 not in (select smile1 from mytable))
структура mytable и dual д/б одинаковы.
Кстати, а разве можно название полей передавать параметром
....select smile1, smile2, smile3 from ....
я вообще не пробовал, но думал, что нет. :-(

:-))))))))))))))))))
любопытно :р1 отобразилось как смайлик. :-)

Это сообщение отредактировал(а) Bes - 30.12.2004, 12:53
PM MAIL   Вверх
Dimich
Дата 30.12.2004, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



Второпях немного неверно написал, надо так:
Код

insert into mytable (f1,f2,f3)
(select :p1, :p2, :p3 from dual where :p1 not in (select f1 from mytable))



Цитата(Bes @ 30.12.2004, 12:49)
Да, в этом ТВОЕМ запросе
insert into mytable (f1,f2,f3)
(select smile1, smile2, smile3 from dual where smile1 not in (select smile1 from mytable))
структура mytable и dual д/б одинаковы.

Пояснение, это для Oracle, DUAL - это мнимая таблица, т.е. объясняя на пальцах, это фишка для того, чтобы можно было сделать
Код

select константа_или_функция from dual


Цитата(Bes @ 30.12.2004, 12:49)
Кстати, а разве можно название полей передавать параметром

А почему бы и нет? У меня ODAC это пропускает без зазрения совести.

И самое главное!

Цитата(Bes @ 30.12.2004, 12:49)
UpdateLitNomStringNew:='update prod set nom = :nom where key = :key and not exists (select * from prod where nom = :onom and data = :odata and stch = :ostch)';

Update это Вам не Insert!

--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
Bes
Дата 31.12.2004, 07:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



2Dimich:
Цитата
Update это Вам не Insert!

В данном случае без разницы - я написал это для демонстрации подзапроса с exists в целях проверки на уникальность записи, но согласен
инсерт не нашел с ходу и не придал этому значения.
А на счет параметров - надо попробовать.

Это сообщение отредактировал(а) Bes - 31.12.2004, 07:15
PM MAIL   Вверх
Dimich
Дата 31.12.2004, 08:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



Цитата(Bes @ 31.12.2004, 07:14)
В данном случае без разницы - я написал это для демонстрации подзапроса с exists в целях проверки на уникальность записи

А вот и не правда ваша! Синтаксис инсертов и апдейтов совершенно разный! Посмотрите спецификацию на SQL! В инсертах не допускается никаких WHERE ни с какими условиями, будь то exist или еще что!!! Опровергните, возьму слова назад.
--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
Bes
Дата 31.12.2004, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 2
Всего: 7



2Dimich: Действительно!!! :-( А я-то думаю, почему я через апдейт сделал - забыл уже. :-)
Однако как-то нелогично это - должен быть способ проверки существующей записи перед вставкой....
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.3728 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.