
Новые сообщения [новые:0]
Дайджест
Горячие темы
Избранное [новые:0]
Форумы
Пользователи
Статистика
Статистика нагрузки
Мод. лог
Поиск
|
|
01.05.2006, 20:08
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Некоторое время назад было глобальное обсуждение того, как получить значение поля со свойством IDENTITY в FoxPro. На сайте www.foxclub.ru выложена новая статья Как прочитать значение поля со свойством IDENTITY Если у кого нет доступа к этому сайту, то тоже самое находится во вложенном файле ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 09:16
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Статья не полная. По какой-то причине не показан способ получения последнего IDENTITY с помощью функции IDENT_CURRENT('table_name'). Иногда эта функция очень полезна. С уважением, Алексей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 09:47
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
2Alexey-K Пример полезности IDENT_CURRENT() в студию! Функция которая работает глобально, может вернуть совершенно левый результат из другой сессии. Для описанного случая вообще неприменима. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 10:48
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Пожалуйста пример: Хранимая процедура добавляет новый документ (документ 1). При этом она пораждает еще другой документ (документ 2), ссылку на который необходимо хранить в документе 1. Для этих целей хранимая процедура запускает транзакцию и добавляет через другую хранимую процедуру документ 2. Затем она читает через IDENT_CURRENT ID таблицы документа 2. После этого хранимая процедура добавляет документ 1 с использованием ID, полученного через IDENT_CURRENT. Почему используется имеено IDENT_CURRENT? Дело в том, что в хранимой процедуре, которая добавляет документ 2, добавляются записи в несколько таблиц со своими IDENTITY, а интересует только IDENTITY конкретной таблицы. На время добавления в таблицу, IDENTITY которой читаем через IDENT_CURRENT, она блокируется с блокировкой SHARED. С уважением, Алексей ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 11:25
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Aleksey-KСтатья не полная. По какой-то причине не показан способ получения последнего IDENTITY с помощью функции IDENT_CURRENT('table_name'). Иногда эта функция очень полезна. Ключевое слово здесь " иногда ". Область применения и использования данной функции чрезвычайно специфическая. Как минимум, ее применение опирается на блокировку всей таблицы, чтобы предотвратить создание новой записи другим пользователем. Т.е. вообще-то, для ее использования надо создать ситуацию, которую всеми силами необходимо избегать! Блокировка всей таблицы на неопределенное время. Кроме того, Вы забываете о чем вообще речь в статье: Добавляется запись в таблицу MS SQL сервера имеющую поле со свойством IDENTITY. Необходимо сразу после создания новой записи получить значение поля со свойством IDENTITY на стороне FoxPro. Ни о каких хранимых процедурах речи вообще не идет. Обычная "тупая" вставка в таблицу. Т.е. одна единственная команда INSERT-SQL. И надо прочитать код вот этой самой, только что добавленой записи вот в эту самую таблицу. КАК в такой постановке задачи может пригодится IDENT_CURRENT()? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 11:31
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
2Aleksey-K Вам не кажется что вместо IDENT_CURRENT() в вашем случае лучше использовать OUTPUT параметры для второй процедуры? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
02.05.2006, 12:05
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Crip2Aleksey-K Вам не кажется что вместо IDENT_CURRENT() в вашем случае лучше использовать OUTPUT параметры для второй процедуры? Имеено так сейчас я и делаю :) Но процедура добавления в таблицу 2 была написана давно, и ее вызовы из клиента уже не переделать так просто. С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
04.05.2006, 10:47
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
ВладимирМ , большое спасибо за статью, очень интересно. Вот если бы расширить статью, чтобы можно было и на Oracle применить нечто похожее, моя благодарность не знала бы границ :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
10.05.2006, 22:42
|
|||
|---|---|---|---|
|
|||
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Hi dmitryx! > Вот если бы расширить статью, чтобы можно было и на Oracle применить нечто > похожее На Oracle таких извращений ВООБЩЕ не требуется (т.к. там нету этого самого IDENTITY). Там всё просто и прямолинейно - прямо ПЕРЕД вставкой записи НА КЛИЕНТЕ ты можешь получить очередное значение SEQUENCE и тут-же его прописать в поле PK, в поля FK и вообще всюду где тебе необходима ссылка на новую запись. Конечно для этого в таблице должен быть прописан адекватный триггер - такой, который не станет БЕЗУСЛОВНО переписывать значение PK поля. Т.е. триггер должен сначала проверить NEW.PK на содержание там чего-либо отличного от NULL - и лишь если там NULL то проводить замену, извлекая очередное значение последовательности. Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
11.05.2006, 08:14
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Igor Korolyov Hi dmitryx! > Вот если бы расширить статью, чтобы можно было и на Oracle применить нечто > похожее На Oracle таких извращений ВООБЩЕ не требуется (т.к. там нету этого самого IDENTITY). Там всё просто и прямолинейно - прямо ПЕРЕД вставкой записи НА КЛИЕНТЕ ты можешь получить очередное значение SEQUENCE и тут-же его прописать в поле PK, в поля FK и вообще всюду где тебе необходима ссылка на новую запись. А между получением "очередного SEQUENCE " и записью ее в качестве ссылки, таблицы будет заблокировна? Слово "тут-же" при записи со стороны клиента вызывает у меня некоторые опасения. Igor Korolyov Конечно для этого в таблице должен быть прописан адекватный триггер - такой, который не станет БЕЗУСЛОВНО переписывать значение PK поля. Т.е. триггер должен сначала проверить NEW.PK на содержание там чего-либо отличного от NULL - и лишь если там NULL то проводить замену, извлекая очередное значение последовательности. А что мешает такой же метод реализовать и в SQL SERVER ? Он даже в учебном курсе MS по SQL Server описан! Для этого достаточно отказаться от IDENTITY, использовать DEFAULT со вставкой "невозможного" PK и написания триггера на INSERT, который этот самый "невозможный" PK заменит на "человеческий". С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
11.05.2006, 12:53
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Здравствуйте Игорь. Собственно идея понятна, я и сам об этом думал. Но с практической реализацией получения NEXTVAL из последовательности при использовании CursorAdapter'a у меня пока-что туговато. Есть мысль в BeforeInsert поместить код получения через SQL Pass-Through NEXTVAL. Но как-то "не аккуратненько" получается :). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
14.05.2006, 19:21
|
|||
|---|---|---|---|
|
|||
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Hi Aleksey! > А между получением "очередного SEQUENCE " и записью ее в качестве ссылки, > таблицы будет заблокировна? Sequence не имеет никакой связи с таблицами - это отдельная сущность. И никаких блокировок не возникает (не считая конечно тех блокировок системных таблиц, которые возникают ВО ВРЕМЯ извлечения очередного значения последовательности - но это мизерное время, AFAIK уменьшаемое к тому-же использованием опции CACHE). Видимо ты не совсем меня понял - я имел в виду работу именно с клиентскими курсорами - т.е. с фоксовым курсором - когда в него идёт вставка записи - а не с серверной таблицей (там конечно тоже на всякий случай прописан код заполнения ID - в BEFORE INSERT триггере). Т.е. мы уже на клиенте получаем "полноценные" записи - с корректными ID/FK - которые потом уже тривиально переносятся в серверные таблицы. > А что мешает такой же метод реализовать и в SQL SERVER? Ничего - за исключением того, что необходимо создать ХП эмулирующую Sequence (aka фоксовый NewID) :) > Он даже в учебном курсе MS по SQL Server описан! Тут как говорится "я не Копенгаген" :) > Для этого достаточно отказаться от IDENTITY Именно так! Просто обычно когда высказываешь такие мысли, SQL-ники тут-же набрасываются с кулаками - видимо этот инструмент является для них священной коровой :) > использовать DEFAULT со вставкой "невозможного" PK и написания триггера на > INSERT, который этот самый "невозможный" PK заменит на "человеческий" Ну наверное в качестве "невозможного" сойдёт и NULL ;) Так что никакого особого Default и не требуется. Тут единственная сложность - позволит ли сервер дойти до триггера, если попытаться таки вставить запись с NULL-ом в качестве PK (например просто не указывая поля PK в списке INSERT). Oracle это позволяет (конечно доходит именно до BEFORE триггера - если мы там не укажем допустимого ID то далее дело не пойдёт). 2 dmitryx Честно говоря, я полагал что если уж нам нужен ID на клиенте, то его надо получать не в BeforeInsert (который исполняется уже при попытке сохранить данные из курсора на сервер - обычно при вызове TableUpdate()), а именно перед вставкой записи в фоксовый курсор. И тут уже нет принципиальной разницы - используется CAD или RV или SPT запросы. Конечно в случае CAD можно прописать в нём самом метод-обёртку для получения очередного значения, и уже этот метод дёргать из основного кода - при этом упрощается миграция на другие СУБД - например на тот-же MS SQL - где вместо SELECT SEQ_SOME.NextVal FROM Dual будет вызываться наша ХП. Или вообще DownSizing на фоксовую базу - где будет вызываться широко известный в узких кругах NewID :) Что же касается случая когда нам на клиенте этот ID не нужен (хотя мне кажется что он нужен практически всегда - уж если и не для вставки связанных записей - в которых надо заполнять поля FK - то хотя-бы для того чтобы после перезапроса вернуться на "ту самую" запись), то тут должен вступать в работу сам сервер - он определяет что с клиента не было задано "подходящего" ID, и сам его прописывает - в триггере конечно. Примерно таком: CREATE OR REPLACE TRIGGER TBI_MyTable BEFORE INSERT ON MyTable FOR EACH ROW BEGIN IF :NEW.ID IS NULL THEN SELECT SEQ_MyTable.NEXTVAL INTO :NEW.ID FROM DUAL; END IF; EXCEPTION WHEN OTHERS THEN NULL; END; Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.05.2006, 11:32
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Игорь, спасибо за помощь. ID нужен действительно на клиенте, и именно для формирования PK и FK. Собственно, я уже все сделал и оно даже работает :). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
15.05.2006, 12:36
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Igor Korolyov Hi Aleksey! Ну наверное в качестве "невозможного" сойдёт и NULL ;) Так что никакого особого Default и не требуется. Тут единственная сложность - позволит ли сервер дойти до триггера, если попытаться таки вставить запись с NULL-ом в качестве PK (например просто не указывая поля PK в списке INSERT). Oracle это позволяет (конечно доходит именно до BEFORE триггера - если мы там не укажем допустимого ID то далее дело не пойдёт). SQL Server даже не позволит сам Constraint создать Primary Key на поле с NULL. Так, что constraint DEFAULT надо создать при таком способе генерации PK. С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
17.05.2006, 02:47
|
|||
|---|---|---|---|
|
|||
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Hi Aleksey! > SQL Server даже не позволит сам Constraint создать Primary Key на поле с > NULL. Вопрос не в этом то :) Вопрос в том, чтобы можно было исполнять команды типа INSERT INTO ... НЕ указывая при этом никакого значения для поля PK - вообще не указывая его в списке заполняемых полей - и оно тогда по умолчанию получается содержит null (в смысле в псевдо-записи видимой в триггере - :NEW в Oracle - реально конечно в таблицу это никогда не запишется - т.к. триггер заменит null на подходящее значение, а если не заменит, то ограничение не пропустит такую запись). А на поле PK естественно установлено ограничение NOT NULL. > Так, что constraint DEFAULT надо создать при таком способе генерации PK. Жаль что SQL Server тут несколько ограничен и требует дополнительных телодвижений портящих всю красоту :( Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
17.05.2006, 08:09
|
|||
|---|---|---|---|
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Igor Korolyov Hi Aleksey! в Oracle - реально конечно в таблицу это никогда не запишется - т.к. триггер заменит null на подходящее значение, а если не заменит, то ограничение не пропустит такую запись). А на поле PK естественно установлено ограничение NOT NULL. Что-то я вас не понял, или ORACLE работатет не так, как MS SQL! В MS SQL у вас просто до триггера дело не дойдет, т.к. ограничитель Primary Key НЕ ПОЗВОЛЯЕТ вставлять NULL в такое поле, а Constraints ВСЕГДА срабатывают РАНЬШЕ,чем AFTER триггеры. Или отказывайтесь от PK Constraint (не рекомендовал бы) или используйте на поле с PK еще и Constraint DEFAULT cо значением, которое триггер НИКОГДА сам не вставит только для того, что бы не сработал Constraint PK и пропустил вставку. По-мойму, красивое и логичное решение. Igor Korolyov Жаль что SQL Server тут несколько ограничен и требует дополнительных телодвижений портящих всю красоту :( См. выше. С уважением, Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|
18.05.2006, 00:48
|
|||
|---|---|---|---|
|
|||
Как прочитать значение поля со свойством IDENTITY |
|||
|
#18+
Hi Aleksey! > Что-то я вас не понял, или ORACLE работатет не так, как MS SQL! Видимо не так... > В MS SQL у вас просто до триггера дело не дойдет, т.к. ограничитель > Primary Key НЕ ПОЗВОЛЯЕТ вставлять NULL в такое поле, а Constraints ВСЕГДА > срабатывают РАНЬШЕ,чем AFTER триггеры. Я писал про BEFORE триггер - он замечательно срабатывает. > По-мойму, красивое и логичное решение. IMHO нет - лишнее телодвижение с DEFAULT -1 (или что там будет в качестве "допустимого но невозможного") всё портит :( Хотя я и не сомневаюсь что оно работоспособное - но в Oracle всё-же выходит "красивше" :) Posted via ActualForum NNTP Server 1.3 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
|
|
|

start [/forum/topic.php?fid=41&mobile=1&tid=1591653]: |
0ms |
get settings: |
8ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
33ms |
get topic data: |
8ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 330ms |

| 0 / 0 |
