powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Перевод из MS SQL Server в ORACLE
25 сообщений из 120, страница 3 из 5
Перевод из MS SQL Server в ORACLE
    #39222159
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты путаешь INSTEAD OF триггер (на VIEW) и COMPAUND триггер. Последний -- это просто объединение триггеров на разные события в одном куске кода, что удобней при использовании например локальных PL/SQL коллекций для обхода той же мутации.
Типо: в секции BEFORE STATEMENT заполняешь коллекцию текущим состоянием, а затем в секциях BEFORE/AFTER EACH ROW проверяешь не нарушает ли условие конкретная запись (на основании коллекции, чтоб не лезть в таблицу). При этом ты, естественно, не видишь изменений других сеансов (добавленных строк, например) и если не предусмотрена какая-либо сериализация (та же блокировка родительской записи) -- все твоя проверка может пойти лесом
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222165
checkъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вячеслав Любомудровcreate trigger contr_trg before insert or update on contractиспользовать триггер для проверки допустимости значения очень однопло.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222168
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не спорю, CHECK намного лучше
А еще и индекс на FOREIGN KEY построить

Но это таки пример -- вводить и объяснять новые понятия нет желания
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222181
dba123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВячеслав Любомудров,

Спасибо. Я понял Вашу мысль. Любое изменение в платежах нужно с помощью триггера отразить в дополнительном поле в контрактах. Если сумма превышает, то тогда и происходит исключение.
ОК. Если не найду другое решение, то так и сделаю.
только внимательней со своим кодом, а то апдейт фк может не сработать, как мне показалось
Код: plsql
1.
update payment set c_id = 1 where c_id = 2;
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222192
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровТы путаешь INSTEAD OF триггер (на VIEW) и COMPAUND триггер. Последний -- это просто объединение триггеров на разные события в одном куске кода, что удобней при использовании например локальных PL/SQL коллекций для обхода той же мутации.
Типо: в секции BEFORE STATEMENT заполняешь коллекцию текущим состоянием, а затем в секциях BEFORE/AFTER EACH ROW проверяешь не нарушает ли условие конкретная запись (на основании коллекции, чтоб не лезть в таблицу). При этом ты, естественно, не видишь изменений других сеансов (добавленных строк, например) и если не предусмотрена какая-либо сериализация (та же блокировка родительской записи) -- все твоя проверка может пойти лесом
Ну допустим, пользователь по конкретному контракту только 1, в смысле если я ввожу данные по одному контракту, то никто параллельно в этот момент не работает с данным контрактам. Соответственно, исключаем возможность других сеансов по конкретной записи. Или другой пример. Допустим я единственный пользователь базы.
Т.е. пусть даже триггер не видит, что делают другие пользователи, а имеет дело только с конкретным пользователем. Я хочу исправить сумму платежа на большую и тут триггер должен меня остановить сообщив об ошибке. Неужели триггер на изменение никак не может просмотреть всю таблицу только по данному контракту? Неужели в корпорации ORACLE не предусмотрели такой поворот событий? Почему то в MS SQL Server нет таких проблем вообще.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222314
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenПочему то в MS SQL Server нет таких проблем вообще.
MS SQL - тупой блокировочник. Фактически, он работает в однопользовательском режиме.
Поэтому у него нет проблем с конкурентным доступом к данным.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222324
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovstudierenПочему то в MS SQL Server нет таких проблем вообще.
MS SQL - тупой блокировочник. Фактически, он работает в однопользовательском режиме.
Поэтому у него нет проблем с конкурентным доступом к данным.

Я с Вами не согласен. В MS SQL Server с одной таблицей могут работать сразу несколько пользователей и при этом триггер спокойно видит все сохранённые данные. Да, там тоже может быть блокировка, но как правило, так происходит если 2 пользователя правят одну и ту же запись. Вот тогда тот, кто успел первым сохранить, то его данные и будут в базе. А у второго - ошибка блокировки. Но на практике одну и ту же запись 2 пользователя почти никогда не правят.
Поэтому кто тупой, MS SQL Server или ORACLE в данном вопросе очень и очень спорно!
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222339
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
dba123studierenВячеслав Любомудров,

Спасибо. Я понял Вашу мысль. Любое изменение в платежах нужно с помощью триггера отразить в дополнительном поле в контрактах. Если сумма превышает, то тогда и происходит исключение.
ОК. Если не найду другое решение, то так и сделаю.
только внимательней со своим кодом, а то апдейт фк может не сработать, как мне показалось
Код: plsql
1.
update payment set c_id = 1 where c_id = 2;

Все, заклевали
Нафиг я сюда вообще влез

studierenНу допустим, пользователь по конкретному контракту только 1, в смысле если я ввожу данные по одному контракту, то никто параллельно в этот момент не работает с данным контрактам. Соответственно, исключаем возможность других сеансов по конкретной записи. Или другой пример. Допустим я единственный пользователь базы.Такие допущения надо чем-то обеспечить
studierenПочему то в MS SQL Server нет таких проблем вообще.Просто они разные
Когда ты изменяешь несколько строк одним оператором и пытаешься (в триггере для каждой обновленной строки) например, подсчитать сумму в этих строках, то возникает вопрос, на какой момент времени брать значения? Точнее даже какой именно из возможных -- ты не можешь управлять порядком обновления/удаления/вставки строк (при многострочной обработке) и при другом порядке (который выбирает Oracle) результат будет другой.

Возьмем твой пример -- ограничить сумму в 1500
Пусть у нас есть строки со значениями: 1000, 500, -1000
Если мы сделаем UPDATE TABLE SET AMOUNT = AMOUNT*3
То, если строки будут обновляться в прямом порядке, то после обновления первой строки мы получим (1000*3)+(500)+(-1000) = 2500, что уже больше 1500, и значит все плохо, так делать нельзя и т.п.
Если же мы обновляем с конца, то после обновления всех строк получаем (1000*3)+(500*3)+(-1000*3) = 1500, что оказывается неплохо, можно даже сказать, хорошо

Вот от такой неоднозначности тебя Oracle и страхует
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222345
dba123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров,

Дык он студент вроде, кто знает, что он там напишет :)
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222351
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВ MS SQL Server с одной таблицей могут работать сразу несколько
пользователей и при этом триггер спокойно видит все сохранённые данные.
Уверен? Проверь на своей схеме следующий сценарий:
1) Сессия 1 стартует транзакцию
2) Сессия 2 стартует транзакцию.
3) Сессия 1 добавляет к документу строку, полностью выбирающую лимит.
4) Сессия 2 добавляет к тому же документу вторую строку, полностью выбирающую лимит.
5) Сессия 1 коммитится.
6) Сессия 2 коммитится.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222430
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пардон, если баян - тему читал по оч. большой диагонали

studieren,

в sql оракловом есть несколько функций каждой из которых достаточно, для создания подходящего вашей теме
проверочного констрейнта

например, ltrim(ляля,'0123456789') is null
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222583
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
orawishпардон, если баян - тему читал по оч. большой диагонали

studieren,

в sql оракловом есть несколько функций каждой из которых достаточно, для создания подходящего вашей теме
проверочного констрейнта

например, ltrim(ляля,'0123456789') is null
Ту проблема я уже решил с помощью regexp_like (спасибо товарищам за подсказку).
Теперь у меня совсем другая проблема.
Когда пользователь правит какую-либо таблицу (мутирующая таблица), то мне необходимо ставить такое ограничение, которое проверяет все записи мутирующей таблицы и если что не так, то запрещает внесение изменений. При этом даже если предположить, что где-то другой пользователь пытается внести изменение в данную таблицу, то эти изменения игнорировать если данные фактически ещё НЕ СОХРАНЕНЫ!
Как это сделать? Не пойму.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222588
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров...
Возьмем твой пример -- ограничить сумму в 1500
Пусть у нас есть строки со значениями: 1000, 500, -1000
Если мы сделаем UPDATE TABLE SET AMOUNT = AMOUNT*3
То, если строки будут обновляться в прямом порядке, то после обновления первой строки мы получим (1000*3)+(500)+(-1000) = 2500, что уже больше 1500, и значит все плохо, так делать нельзя и т.п.
Если же мы обновляем с конца, то после обновления всех строк получаем (1000*3)+(500*3)+(-1000*3) = 1500, что оказывается неплохо, можно даже сказать, хорошо

Вот от такой неоднозначности тебя Oracle и страхует

В MS SQL Server когда массово что-то меняете и при этом хотя бы одна запись даёт "сбой", то сервер запрещает все изменения и происходит откат. Жаль, что в ORACLE не так.

А вообще обычно юзеры штучно правят записи, массово что-то менять может только админ базы или специалист ИТ.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222608
eev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВячеслав Любомудров...
Возьмем твой пример -- ограничить сумму в 1500
Пусть у нас есть строки со значениями: 1000, 500, -1000
Если мы сделаем UPDATE TABLE SET AMOUNT = AMOUNT*3
То, если строки будут обновляться в прямом порядке, то после обновления первой строки мы получим (1000*3)+(500)+(-1000) = 2500, что уже больше 1500, и значит все плохо, так делать нельзя и т.п.
Если же мы обновляем с конца, то после обновления всех строк получаем (1000*3)+(500*3)+(-1000*3) = 1500, что оказывается неплохо, можно даже сказать, хорошо

Вот от такой неоднозначности тебя Oracle и страхует

В MS SQL Server когда массово что-то меняете и при этом хотя бы одна запись даёт "сбой", то сервер запрещает все изменения и происходит откат. Жаль, что в ORACLE не так.

А вообще обычно юзеры штучно правят записи, массово что-то менять может только админ базы или специалист ИТ. ты откуда ж такого фееричного бреда понабрал-то...
а про мутирующие таблицы тебе уже 2 страницы разжевывают. пишет и пишет, говорят ему доку открой, "ну-не-пойму-я" заклинило :).
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222614
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВячеслав Любомудров...
Возьмем твой пример -- ограничить сумму в 1500
Пусть у нас есть строки со значениями: 1000, 500, -1000
Если мы сделаем UPDATE TABLE SET AMOUNT = AMOUNT*3
То, если строки будут обновляться в прямом порядке, то после обновления первой строки мы получим (1000*3)+(500)+(-1000) = 2500, что уже больше 1500, и значит все плохо, так делать нельзя и т.п.
Если же мы обновляем с конца, то после обновления всех строк получаем (1000*3)+(500*3)+(-1000*3) = 1500, что оказывается неплохо, можно даже сказать, хорошо

Вот от такой неоднозначности тебя Oracle и страхует

В MS SQL Server когда массово что-то меняете и при этом хотя бы одна запись даёт "сбой", то сервер запрещает все изменения и происходит откат. Жаль, что в ORACLE не так. Ты нихрена не понял
Вопрос в непредсказуемости результата
studierenА вообще обычно юзеры штучно правят записи, массово что-то менять может только админ базы или специалист ИТ.Какое-то извращенное понятие, можно подумать БД разбирается -- обычный это юзер или "специалист ИТ"
На одиночных обновлениях триггер BEFORE ... FOR EACH ROW тоже отработает без ошибки
Именно потому, что результат детерминирован
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222625
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenВ MS SQL Server когда массово что-то меняете и при этом хотя бы одна
запись даёт "сбой", то сервер запрещает все изменения и происходит откат.
Вот только твой триггер не даст "сбой". Сценарий я описал выше.

Триггерами можно обеспечить целостность группы записей только на уровне изоляции DIRTY
READ. Которого в Oracle нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222640
ну-ну...
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry SibiryakovТриггерами можно обеспечить целостность группы записей только на уровне изоляции DIRTY
READ. Которого в Oracle нет.
целостность и dirty read. целостность можно обеспечить при любом уровне изоляции, кроме dirty read.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222644
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

ОК.
Вот ещё одна проблема. Я должен хранить серийные номера "от" и "до" в разных полях/столбцах. При этом серийные номера не в коем случае не должны пересекаться.
Скажем, в таблице есть такие данные:
От До1 1020 30
Если я попытаюсь ввести диапазон 7 и 11 программа должна ругаться, так как внутри диапазона 1 и 10 уже есть хотя бы как минимум 1 элемент из 7 и 10. Неужели в ORACLE я не смогу создать такой запрет?
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222651
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenНеужели в ORACLE я не смогу создать такой запрет?
Сможешь. Но работать правильно он будет исключительно в однопользовательском режиме. Как и
в любой другой СУБД кроме тех, которые выше DIRTY READ ничего не умеют.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222662
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenТ.е. пусть даже триггер не видит, что делают другие пользователи, а имеет дело только с конкретным пользователем.
В этом то вся и проблема. В этом самом конкретном пользователе. Другие фиг с ними - он не закоммитились - их нет.
Oracle версионник. А это значит, что он не возвращает данные, которые есть в базе. Он возвращает данные на какой-то момент времени (иногда оп выбору иногда на усмотрение сервера). Основная операция еще не завершилась - поэтому ее результата еще нет. И в том числе для триггера. Если так сделать Вы же первый взвоете - какого черта? Ну и в большинстве случаев подобный подход, когда проверяется верность несогласованного набора данных, чаще всего нужно тем, кто хочет совершить ошибку. Поэтому Oraclke СУБД и выплевывает ошибку в этот момент.

Простой пример. Вы всегда хотите, чтобы сумма чего-то разложенного по полкам была равна константе. Тогда Вы не сможете одной операцией увеличить значение на одной полке и уменьшить на другой, если будете проверять сумму по ходу операции. Для этого надо проверять сумму после операции. О чем и сигнализирует ошибка. :)
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222677
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
studierenНеужели в ORACLE я не смогу создать такой запрет?
Можешь. Но делается это иначе. Делается мат вью, которое возвращает количество пересекающихся интервалов, обновляемое по commit. И constraint который не позволяет количеству пересекающихся интервалов быть больше 0.
Одна проверка на транзакцию. Не на каждое изменение.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222688
Сергей Арсеньев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну или iot табличку с уникальными номерами (вставляем для всего диапазона).
Заодно можно получить отлуп (взаимная блокировка), если кто-то еще пытается вместе с вами работать в том же направлении. :)
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222689
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав ЛюбомудровНа одиночных обновлениях триггер BEFORE ... FOR EACH ROW тоже отработает без ошибкиВставках.
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39222708
Вячеслав Любомудров
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ElicВячеслав ЛюбомудровНа одиночных обновлениях триггер BEFORE ... FOR EACH ROW тоже отработает без ошибкиВставках.Упс...
Точно
...
Рейтинг: 0 / 0
Перевод из MS SQL Server в ORACLE
    #39223554
studieren
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вячеслав Любомудров,

Прочёл книжку "ORACLE PL/SQL Как писать мощные и гибкие программы на PL/SQL" Кристофер Аллен.
Там нашёл ответ на свою проблему. Вот отрывок:
Когда триггер пытается прочитать таблицу, а затем записать в нее
данные, возбуждается исключение "мутирующей таблицы". Хотя
намерение ограничить действия такого типа вполне объяснимо,
корпорация Oracle зашла в этом дальше, чем необходимо, запретив
операции, при которых таблица просто блокируется, а не изменяется.
Один из способов обойти эту проблему заключается в том, чтобы
создать вторую таблицу с копиями столбцов, которые триггер должен
прочитать из главной таблицы. В этом случае триггер получает
необходимые значения из второй таблицы, а затем выполняет
запланированные действия с первой таблицей. При реализации
данного подхода важно обеспечить синхронизацию таблиц. Для этого
все операции INSERT, UPDATE и DELETE над главной таблицей
должны отражаться триггером на второй таблице.
Т.е. создаю таблицу точь в точь с "оригиналом", туда добавляю все изменения (вставка, изменение, удаление). Все необходимые мне проверки провожу во второй таблице.
Ну если это единственный способ, что поделать! Буду так. Но я в шоке от корпорации ORACLE.
...
Рейтинг: 0 / 0
25 сообщений из 120, страница 3 из 5
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Перевод из MS SQL Server в ORACLE
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]