Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.08.21;
Скачать: [xml.tar.bz2];

Вниз

КАК отловить, что запись в базе уже СУЩЕСТВУЕТ   Найти похожие ветки 

 
Magic&Wizard   (2003-07-24 20:41) [0]

ВОПРОС: в триггере BEFORE INSERT я делаю проверку, на существование записи. Пусть запись существует, мы это определили.
1) И что делать дальше?
2) Как прервать вставку именно этой записи, и продолжить вставлять все остальные?
3) Действительно ли, это можно сделать только при помощи ХП?

Заранее благодарен


 
VID   (2003-07-25 00:05) [1]

Как ты собираешься определить что в таблице уже имеется "такая" запись ? КАКАЯ ? Запись в которой во всех полях ТЕЖЕ значения что у добавляемой ? ну если так, то...
ДОПУСТИМ У ТЕБЯ В ТАБЛИЦЕ ДВА ПОЛЯ FIELD1 И FIELD2
...................
IF (EXISTS(SELECT * FROM MYTABLE WHERE ("FIELD1"=NEW."FIELD1" AND "FIELD2"=NEW."FIELD2"))) THEN EXCEPTION NO_SAME_RECORDS;
...................

Разумеется в базе должно быть определено исключение NO_SAME_RECORDS

в случае применения вышеуказанного кода, при массовой вставке вставка УЖЕ СУЩЕСТВУЮЩЕЙ записи будет прервана, и при этом будет допустима возможность продолжения вставок в таблицу, т.е. можно будет продолжать процесс массовых вставок записей в тбд (что само собой разумеется)


 
Magic&Wizard   (2003-07-25 03:03) [2]

> VID © (25.07.03 00:05)

Т.е если в ХП по каким то причинам
нельзя проверять допустимость вставки в T2

For Select Field1 from t1 into :P1 do
begin
...
Insert Into T2 (Field1) values (:p1);
...
end;
Этот цикл вставит все записи кроме тех какие
уже есть? Я правильно понял?

Но тогда почему при
create ХП
...
Insert Into T2 (Field1) values ("3434");
Insert Into T2 (Field1) values ("3434");
Insert Into T2 (Field1) values ("3435"); ( Field1) > VID © (25.07.03 00:05)

Т.е если в ХП по каким то причинам
нельзя проверять допустимость вставки в T2

For Select Field1 from t1 into :P1 do
begin
...
Insert Into T2 (Field1) values (:p1);
...
end;
Этот цикл вставит все записи кроме тех какие
уже есть? Я правильно понял?

Но тогда почему при
create ХП
...
Insert Into T2 (Field1) values ("3434");
Insert Into T2 (Field1) values ("3434");
Insert Into T2 (Field1) values ("3435");
Insert Into T2 (Field1) values ("3436");
...
Вылетает Exception и вставка записей не происходит?


 
VID   (2003-07-26 01:24) [3]

а хрен его знает... я вообще то не сталкивался именно с такой задачей... хотя конечно мне кажется такое поведение сервера странным... во всяком случае можно было бы допустит продолжение выполнение кода ХП, видимо EXCEPTION закрывает всю транзакцию в контексте которой выполнялся запрос.
а раз так, и раз в самой ХП производить проверку начилия добавляемой записи невозможно, то придётся тебе реализовать логику ХП на клиенте, к тому же я свой пример когда приводил, подразумевал массовую вставку записей на уровне клиента...


 
kaif   (2003-07-26 02:49) [4]

Вообще дубликаты должны исключаться при помощи UNIQUE INDEX, а не при помощи проверок в триггере вставки, если это сетевая программа и в принципе не исключена неподтвержденная пока еще другая транзакция, вставляющая точно "такую" же запись.
Уточни, какая задача. Если перекачка данных, то можно еще подумать.


 
Sergey Masloff   (2003-07-26 12:08) [5]

kaif © (26.07.03 02:49)
>Вообще дубликаты должны исключаться при помощи UNIQUE INDEX, а >не при помощи проверок в триггере вставки,
Ну то есть UNIQUE INDEX не триггером реализуется? ;-))

>и в принципе не исключена неподтвержденная пока еще другая >транзакция, вставляющая точно "такую" же запись
От такой ситуации не спасет ни UNIQUE ни проверка в триггере. Dirty Read в InterBase слава богу нет.

Magic&Wizard ©
Ты exception отлавливай просто и гаси. И будет тебе "щастье".
Насчет ХП - действительно ЭФФЕКТИВНО это можно сделать через ХП с использованием курсора. Вариант с EXCEPTION затратный по ресурсам.


 
KDS   (2003-07-26 12:40) [6]

CREATE PROCEDURE "Outer_AddToSrcKross" (
"mak1" VARCHAR(30),
"cod1" VARCHAR(30),
"id_m1" INTEGER,
"mak2" VARCHAR(30),
"cod2" VARCHAR(30),
"id_m2" INTEGER)
RETURNS (
"Present" INTEGER)
AS
begin
SELECT count(*) FROM SOURCEKROSS
WHERE ((Cod1=:"cod1" and maker1=:"mak1") and (Cod2=:"cod2" and maker2=:"mak2"))
or ((Cod1=:"cod2" and maker1=:"mak2") and (Cod2=:"cod1" and maker2=:"mak1"))
( "Present"=0) CREATE PROCEDURE "Outer_AddToSrcKross" (
"mak1" VARCHAR(30),
"cod1" VARCHAR(30),
"id_m1" INTEGER,
"mak2" VARCHAR(30),
"cod2" VARCHAR(30),
"id_m2" INTEGER)
RETURNS (
"Present" INTEGER)
AS
begin
SELECT count(*) FROM SOURCEKROSS
WHERE ((Cod1=:"cod1" and maker1=:"mak1") and (Cod2=:"cod2" and maker2=:"mak2"))
or ((Cod1=:"cod2" and maker1=:"mak2") and (Cod2=:"cod1" and maker2=:"mak1"))
into :"Present";

if ("Present"=0) then
insert into sourcekross (MAKER1,COD1,id_mak1,MAKER2,COD2,id_mak2,DATECOMMENT)
values (:"mak1", :"cod1", :"id_m1", :"mak2", :"cod2", :"id_m2", "NOW");
end


 
kaif   (2003-07-26 15:30) [7]

2 Sergey Masloff (26.07.03 12:08)
Вы неправы. Допустим нет уникального индекса.
1.Стартует 1-я транзакция. Insert. Триггер вставки проверяет на наличие дубликата. Все нормально, insert прошел.
2.Стартует 2-я транзакция. Insert. Триггер вставки проверяет на наличие дубликата. Все нормально, insert опять прошел.
3.Подтверждается 1-я транзакция
4.Подтверждается 2-я транзакция.
5.В таблице налицо 2 одинаковые записи.
(Этот пример приводил Alexandr пару месяцев назад)
------
Если же имеется UNIQUE KEY, то при попытке подтвердить вторую транзакцию произойдет нарушение ключа и дубликата в таблице не возникнет.
Хотя для некоторых задач (нет работы в сети, база захвачена монопольно (shutdown) и идет лишь перекачка данных) приемлемо делать проверку в триггере вставки.
Для таких случаев try-except-end на клиенте может быть не лучшим решением. Поэтому задача требует уточнения. Зачем автору нужно проверять на дубликатность? Цель?


 
Reindeer Moss Eater   (2003-07-26 15:32) [8]

1.Стартует 1-я транзакция. Insert. Триггер вставки проверяет на наличие дубликата. Все нормально, insert прошел.
2.Стартует 2-я транзакция. Insert. Триггер вставки проверяет на наличие дубликата. Все нормально, insert опять прошел.


Справедливо, но лишь для ограниченного количества случаев.


 
kaif   (2003-07-26 15:42) [9]

2 Reindeer Moss Eater (26.07.03 15:32)
>Справедливо, но лишь для ограниченного количества случаев.
Да я и не спорю.
Просто уникальный ключ гарантирует, что дубликатов не будет ни при каких условиях и ни при каких случаях. А остальные подходы этого не гарантируют. Поэтому я и настаиваю на уточнении задачи.
И если бы я не был свидетелем многократных попыток разработчиков использовать проверку в триггере вместо применения уникального ключа, я бы вообще не заикался здесь на эту тему.
И откладывать это на потом неверно. Например, если в самом начале разработки базы выбраны слишком широкие поля, то потом, возможно, индекс построить и не удастся вообще. И если это "тот случай", то задача будет решена криво или придется все переделывать и перекачивать данные.


 
Sergey Masloff   (2003-07-26 15:47) [10]

kaif © (26.07.03 15:30)
>2 Sergey Masloff (26.07.03 12:08)
>Вы неправы. Допустим нет уникального индекса.
Ваш пример справедлив. Я что-то второпях неправильно понял как вопрос так и ответ ;-)


 
Reindeer Moss Eater   (2003-07-26 15:51) [11]

Пример справедлив для TIL ReadCommitted и RepeatableRead.
Для DirtyRead он несправедлив.
Хотя конечно, я бы и не стал так проверять уникальность записи.


 
Sergey Masloff   (2003-07-26 16:35) [12]

Reindeer Moss Eater (26.07.03 15:51)
>Пример справедлив для TIL ReadCommitted и RepeatableRead.
>Для DirtyRead он несправедлив

Написано же ж
[D7, IB6.x]
откуда там DirtyRead?


 
Reindeer Moss Eater   (2003-07-26 16:40) [13]

Примерно с середины этой ветки разговор перешел с собственно вопроса на общие принципы бизнес правил.


 
Magic&Wizard   (2003-07-26 18:23) [14]

Всем спасибо.
Хорошо, уточняю вопрос:
1) существует общая база ~5-6 Gb
1.1) во всех таблицах существуют ID поля
2) из нее делается выборка записей по некоторому набору параметров, определяемому пользователем (параметров около 150)
3) эта выборка весит в среднем от 500mb до 1 Gb, и нуждается в сохранении для передачи клиенту, дальше он делает с ней что хочет :) (может из своего куска делать свои выборки и сохранять)

ВОПРОС: Как эффективно реализовать сохранение?


 
VID   (2003-07-26 23:00) [15]

Насколько я понимаю, пользователь после выбора 150-ти параметров :) нажимает какую-нить кнопку "ОК" и его клиентской прогой выполняется ХП, которая и возвращает записи клиенту...

И единственной проблемой является то, что необходимо следить за тем что бы пользователю не попались абсолютно одинаковые записи ? так что ли ? если так, то эту задачу необходимо реализовать ещё на том этапе, когда происходит ДОБАВЛЕНИЕ записей в таблицу-источник_выборки... с помощью уникальных индексов, как уже говорил kaif...


 
Dick Gonsales   (2003-07-28 06:16) [16]

ВОПРОС: в триггере BEFORE INSERT я делаю проверку, на существование записи. Пусть запись существует, мы это определили.
1) И что делать дальше?
2) Как прервать вставку именно этой записи, и продолжить вставлять все остальные?
3) Действительно ли, это можно сделать только при помощи ХП?


1) Ничего не делать (если тебе не надо сохранять лог ошибочных записей, иначе их надо инсертить в другую таблицу), по моему в IB это можно реализовать insert существующеми значениями, не факт что только так... то есть field.new:=field.old
2) Вопрос снимается ответом 1)
3) Нет.

Вообще если честно Magic&Wizard не очень понятно что тебе надо...
Если тебе надо слить в бок не повторяющиеся записи, то вариантов вагон и маленькая тележка, в зависимости от бизнес логики процесса как ты сливаешь.
Вариант 1.
Сливается все за один раз в пустую таблицу
а) SELEST DISTINCT
б) SELECT *
UNION
( SELECT count(*) ВОПРОС: в триггере BEFORE INSERT я делаю проверку, на существование записи. Пусть запись существует, мы это определили.
1) И что делать дальше?
2) Как прервать вставку именно этой записи, и продолжить вставлять все остальные?
3) Действительно ли, это можно сделать только при помощи ХП?


1) Ничего не делать (если тебе не надо сохранять лог ошибочных записей, иначе их надо инсертить в другую таблицу), по моему в IB это можно реализовать insert существующеми значениями, не факт что только так... то есть field.new:=field.old
2) Вопрос снимается ответом 1)
3) Нет.

Вообще если честно Magic&Wizard не очень понятно что тебе надо...
Если тебе надо слить в бок не повторяющиеся записи, то вариантов вагон и маленькая тележка, в зависимости от бизнес логики процесса как ты сливаешь.
Вариант 1.
Сливается все за один раз в пустую таблицу
а) SELEST DISTINCT
б) SELECT *
UNION
SELECT *
Вариант 2.
Сливается в какую-то таблицу, где есть записи
а) Вариант KDS, только я бы написал в одну фразу, Insert <..> WHERE <..> AND 0 in (SELECT count(*) FROM <.проверка на существование.>)
б) Через EXCEPTION, в котором ничего не происходит, по синтаксису в IB я не помню точно как это, в Oracle достаточно поставить магическое слово null. При этом если записи не проходят по ограничению, то выполнение ХР не прерывается но запись не вставляется.
Вариант 3.
Чисто по мне самый двинутый, исходя из опыта построения и эксплуатации SQL ИС - через триггер ответ выше...
А вообще сам вопрос ва чем проблема не очень понятен...


 
Magic&Wizard   (2003-07-28 11:22) [17]

Всем спасибо...



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.08.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.008 c
9-68143
YO
2003-02-19 14:23
2003.08.21
КАК Вывести на экран Opengl А


6-68424
ga3
2003-06-03 17:18
2003.08.21
и снова TWebBrowser:-)


1-68386
Still Swamp
2003-08-07 18:38
2003.08.21
Указатель на функцию


14-68555
FreeSky
2003-08-04 17:45
2003.08.21
Нужны компоненты TAPI желательно с русским описанием...


14-68497
Мг. Гад
2003-08-05 23:37
2003.08.21
Усех сосчитаю





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский