Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как прочитать значение поля со свойством IDENTITY / 18 сообщений из 18, страница 1 из 1
01.05.2006, 20:08
    #33700472
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Некоторое время назад было глобальное обсуждение того, как получить значение поля со свойством IDENTITY в FoxPro.

На сайте www.foxclub.ru выложена новая статья

Как прочитать значение поля со свойством IDENTITY

Если у кого нет доступа к этому сайту, то тоже самое находится во вложенном файле
...
Рейтинг: 0 / 0
02.05.2006, 09:16
    #33700832
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Статья не полная.
По какой-то причине не показан способ получения последнего IDENTITY с помощью функции IDENT_CURRENT('table_name'). Иногда эта функция очень полезна.

С уважением, Алексей
...
Рейтинг: 0 / 0
02.05.2006, 09:47
    #33700883
Crip
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
2Alexey-K
Пример полезности IDENT_CURRENT() в студию!
Функция которая работает глобально, может вернуть совершенно левый результат из другой сессии. Для описанного случая вообще неприменима.
...
Рейтинг: 0 / 0
02.05.2006, 10:48
    #33701021
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Пожалуйста пример:
Хранимая процедура добавляет новый документ (документ 1). При этом она пораждает еще другой документ (документ 2), ссылку на который необходимо хранить в документе 1. Для этих целей хранимая процедура запускает транзакцию и добавляет через другую хранимую процедуру документ 2. Затем она читает через IDENT_CURRENT ID таблицы документа 2. После этого хранимая процедура добавляет документ 1 с использованием ID, полученного через IDENT_CURRENT. Почему используется имеено IDENT_CURRENT? Дело в том, что в хранимой процедуре, которая добавляет документ 2, добавляются записи в несколько таблиц со своими IDENTITY, а интересует только IDENTITY конкретной таблицы. На время добавления в таблицу, IDENTITY которой читаем через IDENT_CURRENT, она блокируется с блокировкой SHARED.

С уважением, Алексей
...
Рейтинг: 0 / 0
02.05.2006, 11:25
    #33701133
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Aleksey-KСтатья не полная.
По какой-то причине не показан способ получения последнего IDENTITY с помощью функции IDENT_CURRENT('table_name'). Иногда эта функция очень полезна.
Ключевое слово здесь " иногда ".

Область применения и использования данной функции чрезвычайно специфическая. Как минимум, ее применение опирается на блокировку всей таблицы, чтобы предотвратить создание новой записи другим пользователем.

Т.е. вообще-то, для ее использования надо создать ситуацию, которую всеми силами необходимо избегать! Блокировка всей таблицы на неопределенное время.

Кроме того, Вы забываете о чем вообще речь в статье:

Добавляется запись в таблицу MS SQL сервера имеющую поле со свойством IDENTITY. Необходимо сразу после создания новой записи получить значение поля со свойством IDENTITY на стороне FoxPro.

Ни о каких хранимых процедурах речи вообще не идет. Обычная "тупая" вставка в таблицу. Т.е. одна единственная команда INSERT-SQL. И надо прочитать код вот этой самой, только что добавленой записи вот в эту самую таблицу.

КАК в такой постановке задачи может пригодится IDENT_CURRENT()?
...
Рейтинг: 0 / 0
02.05.2006, 11:31
    #33701163
Crip
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
2Aleksey-K
Вам не кажется что вместо IDENT_CURRENT() в вашем случае лучше использовать OUTPUT параметры для второй процедуры?
...
Рейтинг: 0 / 0
02.05.2006, 12:05
    #33701278
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Crip2Aleksey-K
Вам не кажется что вместо IDENT_CURRENT() в вашем случае лучше использовать OUTPUT параметры для второй процедуры?
Имеено так сейчас я и делаю :)
Но процедура добавления в таблицу 2 была написана давно, и ее вызовы из клиента уже не переделать так просто.
С уважением, Алексей.
...
Рейтинг: 0 / 0
04.05.2006, 10:47
    #33706033
dmitryx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
ВладимирМ , большое спасибо за статью, очень интересно.
Вот если бы расширить статью, чтобы можно было и на Oracle применить нечто похожее, моя благодарность не знала бы границ :)
...
Рейтинг: 0 / 0
10.05.2006, 22:42
    #33719041
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Hi dmitryx!

> Вот если бы расширить статью, чтобы можно было и на Oracle применить нечто
> похожее

На Oracle таких извращений ВООБЩЕ не требуется (т.к. там нету этого самого
IDENTITY). Там всё просто и прямолинейно - прямо ПЕРЕД вставкой записи НА
КЛИЕНТЕ ты можешь получить очередное значение SEQUENCE и тут-же его
прописать в поле PK, в поля FK и вообще всюду где тебе необходима ссылка на
новую запись.
Конечно для этого в таблице должен быть прописан адекватный триггер - такой,
который не станет БЕЗУСЛОВНО переписывать значение PK поля. Т.е. триггер
должен сначала проверить NEW.PK на содержание там чего-либо отличного от
NULL - и лишь если там NULL то проводить замену, извлекая очередное значение
последовательности.

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
11.05.2006, 08:14
    #33719289
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
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 заменит на "человеческий".
С уважением, Алексей.
...
Рейтинг: 0 / 0
11.05.2006, 12:53
    #33720165
dmitryx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Здравствуйте Игорь.

Собственно идея понятна, я и сам об этом думал. Но с практической реализацией получения NEXTVAL из последовательности при использовании CursorAdapter'a у меня пока-что туговато.

Есть мысль в BeforeInsert поместить код получения через SQL Pass-Through NEXTVAL. Но как-то "не аккуратненько" получается :).
...
Рейтинг: 0 / 0
14.05.2006, 19:21
    #33725539
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
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
...
Рейтинг: 0 / 0
15.05.2006, 11:32
    #33726439
dmitryx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Игорь, спасибо за помощь. ID нужен действительно на клиенте, и именно для формирования PK и FK. Собственно, я уже все сделал и оно даже работает :).
...
Рейтинг: 0 / 0
15.05.2006, 12:36
    #33726731
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Igor Korolyov
Hi Aleksey!
Ну наверное в качестве "невозможного" сойдёт и NULL ;) Так что никакого
особого Default и не требуется. Тут единственная сложность - позволит ли
сервер дойти до триггера, если попытаться таки вставить запись с NULL-ом в
качестве PK (например просто не указывая поля PK в списке INSERT). Oracle
это позволяет (конечно доходит именно до BEFORE триггера - если мы там не
укажем допустимого ID то далее дело не пойдёт).

SQL Server даже не позволит сам Constraint создать Primary Key на поле с NULL.
Так, что constraint DEFAULT надо создать при таком способе генерации PK.
С уважением, Алексей.
...
Рейтинг: 0 / 0
17.05.2006, 02:47
    #33731303
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
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
...
Рейтинг: 0 / 0
17.05.2006, 08:09
    #33731440
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
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 тут несколько ограничен и требует дополнительных
телодвижений портящих всю красоту :(

См. выше.
С уважением, Алексей.
...
Рейтинг: 0 / 0
18.05.2006, 00:48
    #33734167
Igor Korolyov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Hi Aleksey!

> Что-то я вас не понял, или ORACLE работатет не так, как MS SQL!

Видимо не так...

> В MS SQL у вас просто до триггера дело не дойдет, т.к. ограничитель
> Primary Key НЕ ПОЗВОЛЯЕТ вставлять NULL в такое поле, а Constraints ВСЕГДА
> срабатывают РАНЬШЕ,чем AFTER триггеры.

Я писал про BEFORE триггер - он замечательно срабатывает.

> По-мойму, красивое и логичное решение.

IMHO нет - лишнее телодвижение с DEFAULT -1 (или что там будет в качестве
"допустимого но невозможного") всё портит :( Хотя я и не сомневаюсь что оно
работоспособное - но в Oracle всё-же выходит "красивше" :)

Posted via ActualForum NNTP Server 1.3
...
Рейтинг: 0 / 0
18.05.2006, 21:08
    #33736997
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как прочитать значение поля со свойством IDENTITY
Вот теперь все понятно!
MS SQL Server 2000 нет триггеров BEFORE :(
Можно правда использовать для этих целей триггер INSTEAD OF ..., но это другая тема.
Спасибо.
С уважением, Алексей
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Как прочитать значение поля со свойством IDENTITY / 18 сообщений из 18, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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