![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Удаление записей из одной таблицы по ключам другой таблицы [D6, Sybase ASA]
Курдль © (2004-04-28 23:58:00)1. База построена криво, - не сыпьте соль на ...
2. Перепланировать ее нельзя никоим образом - ни процедур ни даже временных таблиц.
Описание:
Есть таблица СПРАВКИ ПК: СПР_ИД
Есть таблица ПЛАТЕЖИ, ссылающаяся на справки "одна-к-одной" по внешнему ключу ВК_СПР_ИД.
Теперь внимание! Вопрос: надо удалить те, и только те СПРАВКИ, на которые ссылается группа ПЛАТЕЖЕЙ.
Если кто не понял, проблема в том, что сначала надо обнулить значение внешних ключей из ПЛАТЕЖЕЙ, а потом удалить соответствующие обнуленнымключам справки.
Не предлагать:
1. Сделать селект и в цикле обнулять по одному сначала ключи (запоминая их значение), а потом удалять СПРАВКУ со СПР_ИД равной этому значению.
2. Предлагать все остальное :) Хотелось бы какой-нить шайтан скрипт :)
Sandman25+1 (2004-04-29 17:28:00) [1][28] Курдль © (29.04.04 17:24)
Виноват, невнимательно посмотрел. Точнее, посчитал, что нельзя изменять процедуры (понятно, почему) и добавлять таблицы (чтобы не увеличивать требования к памяти). Жаль, что ХП выполняется быстрее, чем автономный скрипт.
Курдль (2004-04-29 17:24:00) [2]
> Само собой, никто бы не советовал написать хранимую процедуру
И правильно не советовали, особенно те, кто внимательно читал условие - нельзя вмешиваться в структуру базы!
Вот в конце концов был рожден (не помню, как он обзывается) типа анонимный (или автономный) скрипт.
Sandman25+1 (2004-04-29 17:20:00) [3][26] Курдль © (29.04.04 17:07)
Само собой, никто бы не советовал написать хранимую процедуру, все обожают такое делать через TTable... :)
Курдль (2004-04-29 17:07:00) [4]
> Так бы сразу и сказал :))))
Чё за грязные инсиннуации? :))) Это про мой скрипт, который так именно и делает? :)))
Я просто переделываю модуль, созданный одним юным дарованием, так у него на клиентебыл сделан цикл по выборке из ПЛАТЕЖЕЙ, в каждом проходе которого на сервер посылалось немеряное кол-во запросов.
Sandman25+1 (2004-04-29 17:02:00) [5][23] Курдль © (29.04.04 14:11)
Constraint не меняется. Ни рядовым юзером, ни DBA. Он всего навсего временноотключается, чтобы можно было работать с таблицами в любом порядке (а не в том, который требуют констрейнты).
Не предлагать:
1. Сделать селект и в цикле обнулять по одному сначала ключи (запоминая их значение), а потом удалять СПРАВКУ со СПР_ИД равной этому значению.
Так бы сразу и сказал :))))
Курдль (2004-04-29 15:30:00) [6]Доклад: зачётно отработал скрипт
begin
for LP as CR cursor for select INQ_ID as CUR_INQ from SC.SC_AGENT_PAYMENTS where AGR_ID = :AGR_ID do
update SC.SC_AGENT_PAYMENTS set INQ_ID = Null where INQ_ID = CUR_INQ;
delete SC.SC_INQUIRYES where INQ_ID = CUR_INQ;
end for;
end;
Спасибо всем-всем-всем, а особенно Danilka © за хорошую наводку!
ЗЫ: Люблю Sybase!
Курдль (2004-04-29 14:11:00) [7]
> DEFERRED
Нет даже такого зарезервированного слова. И в работе с констрэйнтами ничего про рилтайм (тока создал/удалил).
Да и вряд ли установленные нами же правила дали бы менять констрэйнты рядовому юзеру.
To Danilka © - попробую родить скрипт. Тестовый скрипт отработал с компонентом TSDQuery и TSDScript - зачет!
Окончательные результаты доложу.
> СиБэйз подобен мсскл (или наоборот) блокировочники..
MS SQL делался по образу и подобию. Не знаю, насколько удачно.
Sandman25+1 (2004-04-29 13:53:00) [8][13] Курдль © (29.04.04 12:46)
СУБД Informix:
BEGIN WORK;
SET CONSTRAINT my_foreign_key DEFERRED;
-- работа с БД
-- ...
COMMIT WORK
Еще можно SET CONSTRAINTS ALL DEFERRED - отключает вообще все constraints
roottim (2004-04-29 13:44:00) [9]2Danilka © (29.04.04 13:30) [20]
> Скорее всего, в сибейсе подобное тоже возможно. и никаких темповых таблиц.
Наврядли. Оракл версионник... и данные по вышему курсору будут браться из сегмента отката.
СиБэйз подобен мсскл (или наоборот) блокировочники.. и выходом из ситуации для них служат созданные временные таблицы. (по этой-же причине в Оракл временные таблицы ранее не использовалиь вообще. Да и сейчас необходимы для частных(редких) удобств)
2 Курдль
а сибэйз не может как мсскл (вроде одного поля ягоды) типа:
select * штещ #temp from mytable
Danilka (2004-04-29 13:30:00) [10]Все-таки, в орокле, вероятно, я-бы сделал примерно так:
begin
for i in (select ... from ПЛАТЕЖИ where ...) loop
-- удаляем справки
-- апдейтим поле
end loop;
end;
Скорее всего, в сибейсе подобное тоже возможно. и никаких темповых таблиц.
Курдль (2004-04-29 13:23:00) [11]
> Я не знаю, как организована поддержка временных таблиц в
> сибейсе.
> Может достаточно просто создавать пользовательскую тбл,
> а потом убивать... Я не знаю, как организована поддержка
> прав в сибейсе.
Как во всякой взрослой базе. Естественно, когда нами конкретная база проектировалась, никто и представить не мог такой крамолы, чтобы дать юзерам возможность создавать таблицы. Плохо, что нет времени и сил углубляться в частности типа чемcreate global temporary table...отличается отcreate local temporary table.... Естественно, что все эти варианты я попробовал и они либо выдали ошибки, либо не подошли, прежде чем я потревожил мастеров. :(
Johnmen (2004-04-29 13:17:00) [12]Я не знаю, как организована поддержка временных таблиц в сибейсе.
Может достаточно просто создавать пользовательскую тбл, а потом убивать... Я не знаю, как организована поддержка прав в сибейсе.
Курдль (2004-04-29 13:16:00) [13]
> в орокле такое можно, посылаешь блок begin ... end; в ms-sql
> тоже можно, а в сабейсе разве нельзя?
В Sybase чёрта лысого сделать можно - хоть запросы на Java писать, поэтому в его доке запутаться - как 2 факса отослать! Но позволят ли компоненты (SQL Direct)?.. Однако надо сначала попробовать в "Interactive SQL".
Курдль (2004-04-29 13:13:00) [14]
> Т.о. единственное решение видится в применении временной
> таблицы.
А вот вопросец... Каким образом незаметненькосоздать временную таблицу? Если в лоб пишешьselect temporary table ...- нарываешься на нарушение прав. Роль юзера, который должен работать с этими таблицами распространяется только на добавление/изменение/удаление записей.
Danilka (2004-04-29 13:10:00) [15]а в Sybase можно скрипты на исполнение посылать?
не процедуру, не запрос, а скрипт.
который будет делать, например, курсор на одну таблицу, в цикле этого курсора два запроса: на удаление из второй таблицы и апдейт текущей записи, записать в ее поле null.
в орокле такое можно, посылаешь блок begin ... end; в ms-sql тоже можно, а в сабейсе разве нельзя?
Johnmen (2004-04-29 12:57:00) [16]>Курдль © (29.04.04 12:46) [13]
Тогда твоя проблема, в данной постановке, неразрешима (за искл.см.ниже).
Основание :
Надо сделать модификацию данных одной тбл, потом модификацию данных другой тбл, причем критерий для 2тбл берется на основании критерия для 1тбл. Значит параметры второй модификации зависят от первой, т.е. должен быть "мостик" данных.
Т.о. единственное решение видится в применении временной таблицы.
Курдль (2004-04-29 12:46:00) [17]
> Sandman25+1 (29.04.04 09:48) [4]
> 1. Если в Sybase есть способ временно отключить Foreign Key
Приведи пример такой возможности из любой другой базы - я попробую порыть в доке Сайбэйса (мож не заметил чего).
> Johnmen © (29.04.04 11:24) [12]
> Почему крайняя ? Переопредели FK.
> ... ON DELETE SET NULL
У меня нет права просто так взять и вмешаться в структуру БД, которая оттачивалась месяцами и на которой ныне работают несколько крупных фирм. Для этого должны быть веские основания. Когда я говорил о кривизне базы - имел в виду, что это громоздкое, но рабочее сооружение с огромным количеством компромиссов.
Johnmen (2004-04-29 11:24:00) [18]>Курдль © (29.04.04 10:55) [11]
Почему крайняя ? Переопредели FK.
... ON DELETE SET NULL
Курдль (2004-04-29 10:55:00) [19]Для всех: все именно так, как я описал один-к-одному.
> Отсюда вопрос - можешь ли изменить описание внешнего ключа
> ?
Это крайняя мера, к которой прибегну в последний момент
check on commit
Johnmen (2004-04-29 10:40:00) [20]>Курдль ©
Я кажись понял, в чем проблема....
Отсюда вопрос - можешь ли изменить описание внешнего ключа ?