![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Каким образом получить только что вставленную в таблицу базы? [MSSQL]
Lex_! © (2006-06-21 10:39:00)Доброго времени суток.
Вопрос собственно: каким образом можно получить только что вставленную запись? Допустим в запросе, при вставлении записи генерируется id (уникальный идентификатор вида: {F3758C08-7BA6-4251-8BC3-C2A4476E17D3}) - каким образом можно сразу же получить этот идентификатор? (с момента вставки записи и до момента выполнения запроса на выборку может быть вставлено еще несколько записей... )
AxelBlack (2006-06-21 15:42:00) [21]
> Lex_! © (21.06.06 10:39)
> Доброго времени суток.
> Вопрос собственно: каким образом можно получить только что
> вставленную запись?
>...(с момента вставки записи и до момента выполнения запроса на выборку
>может быть вставлено еще несколько записей... )
Как раз только что закончил тестировать такую же задачу:
Необходимо генерировать уникальный ID int и возвращать клиенту (под MSSQL). Надо - быстро и без ошибок.
Сделал так:
- update и select после него положил в stored procedure одной транзакцией (перформанс (время обработки, или же время затраченное на отправку запроса, его обработку сервером и возвращение результата) достигается тем, что план выполнения помещается в кеш и все происходит на стороне SQL сервера, а не на клиенте)
- вызываю ее через ADOStoredProc с параметрами
Сделал тест с 20 потоками и 1000 вызовов на каждый поток.
Причем:
если в ADOStoredProcedure напрямую задавать ConnectionString
(ConnectionString := fTestGetNextIDTestTable.ADOConnection.ConnectionString), то все ОК, скорость - 6 sec.;
если использовать Connection и задавать в нем один общий ADOConnection
(Connection := fTestGetNextIDTestTable.ADOConnection), то на 20.000 обращений 6 неудачных запросов на новый ID, скорость - намного (!!!) медленнее.
Всего доброго,
Axel
Val (2006-06-21 13:02:00) [22]>[28] sniknik © (21.06.06 12:42)
а так, под "прерыванием" имелось ввиду что-то типа "грязного чтения"..
ну да, остальным ничего не выгорит, конечно :)
Lex_! (2006-06-21 12:57:00) [23]Ага, спасибо, понятно, будем рыть дальше...
ЗЫ - и почему борланд не сделал работу с сессиями в WebBroker'е... :)
sniknik (2006-06-21 12:50:00) [24]> вообще речь шла о том что у переменной в другом потоке возможно будет такое же значение
ну про то что гуид уникален уже не раз выше говорили, и это не фича mssql (как генератор в IB), это фича системы, т.е. где бы не получил 2 гуида фукцией создания они будут уникальны.
Lex_! (2006-06-21 12:46:00) [25]
> т.е. где бы паралельный поток не вклинился, команду выполнить,
> на переменную по всему ходу скрипта у него влияния нет
>
вообще речь шла о том что у переменной в другом потоке возможно будет такое же значение ... но если такого не может быть то вопрос исчерпан.. :)
sniknik (2006-06-21 12:42:00) [26]> в смысле? а "прибивание" пользовательской сессии админом? или мы о разном?
а х.з. я уже чегото не уверен ;).
давай "по полкам"
Set NoCount ON
Declare @GUID uniqueidentifier --определили переменную (видимость только в этом пакете "извне" не изменить)
Select @GUID=newid() -- дали переменной значение
Insert into Table (ID, .....) Values (@GUID, .....) -- вставили в таблицу
Set NoCount OFF
Select GUID=@GUID -- вернули переменную
т.е. где бы паралельный поток не вклинился, команду выполнить, на переменную по всему ходу скрипта у него влияния нет (локальнная), чтения из таблицы (последнего значения например после долгих запросов) нет, т.е. то что другой поток может поменять, не используется, а используется локальная переменная которую и записывают и наружу выдают. т.е. прервать процесс не должен.
про админа мысль совсем не понял.
Ega23 (2006-06-21 12:38:00) [27]
> да это так, но я не знаю - генерит ли эта функция гуид просто,
> либо еще занимается какой-то фигней типа "заюзали его или
> нет", поэтому и спросил на всякий случай. спасибо, не буду
> флеймить.
Насколько я понимаю, просто генерит и всё.
Val (2006-06-21 12:28:00) [28]>[24] sniknik © (21.06.06 12:24)
в смысле? а "прибивание" пользовательской сессии админом? или мы о разном?
Val (2006-06-21 12:26:00) [29]>[23] Ega23 © (21.06.06 12:22)
да это так, но я не знаю - генерит ли эта функция гуид просто, либо еще занимается какой-то фигней типа "заюзали его или нет", поэтому и спросил на всякий случай. спасибо, не буду флеймить.
sniknik (2006-06-21 12:24:00) [30]> т.е. одновременно можно считать из разных приложений, а в примере два последовательных запроса ...
> немножко не то ...
пример неправильный, но прерватся один пакет другим, из другой сессии, программы все одно не может. иначе давно уже на "многоюзерских" системах все в коллизиях "захлебнулись" бы.
Ega23 (2006-06-21 12:22:00) [31]
> Разница в возможности повторной генерации одного и того
> же значения для нескольких различных транзакций, в случае
> отката предыдущих. Т.е не использовался в неудачной - отдали
> его же опять другой транзакции.
Насколько мне известно, GUID в один момент времени может быть только один. В другой он будет уже другой.
Ega23 (2006-06-21 12:20:00) [32]
> Теперь не по теме скажу. Это не то немножко в примере ..
> .
> Имелось ввиду что запросы выполняются в разных сессиях,
> т.е. одновременно можно считать из разных приложений, а
> в примере два последовательных запроса ... немножко не то
> ...
Без разницы. Кстати, коли в разных сессиях исполняется, то и ProcessID разный будет. А функция NewID() ВСЕГДА вернёт тебе УНИКАЛЬНЫЙ идентификатор.
> Вот именно, в Мелкософте не идиоты, чтобы выполнять запросы
> по очереди, есть приложения где запросы выполняются до получаса.
> . хотите сказать что остальные будут ждать пол часа пока
> выполнится запрос?... Сомневаюсь .. остальные запросы тоже
> будут выполняться.. :)
Ты бы попробовал и проверил, прежде чем за утверждения кидаться...
sniknik (2006-06-21 12:19:00) [33]сорри, в проверку ([17]) "закралась" ошибка (пробовал на таблице где одно поле NOT NULL) т.е. оно у меня в любом случае не пишется ни в первую ни во вторую строку, потому и зделал ошибочный вывод о автотранзакци на весь блок...
спасибо подсказали.
Val (2006-06-21 12:19:00) [34]>Ega23 © (21.06.06 11:38)
Разница в возможности повторной генерации одного и того же значения для нескольких различных транзакций, в случае отката предыдущих. Т.е не использовался в неудачной - отдали его же опять другой транзакции.
Спасибо, про отсутствие генераторов в МС СКЛ я в курсе.
Lex_! (2006-06-21 12:17:00) [35]
> sniknik
Теперь не по теме скажу. Это не то немножко в примере ...
Имелось ввиду что запросы выполняются в разных сессиях, т.е. одновременно можно считать из разных приложений, а в примере два последовательных запроса ... немножко не то ...
> Ega23
Вот именно, в Мелкософте не идиоты, чтобы выполнять запросы по очереди, есть приложения где запросы выполняются до получаса.. хотите сказать что остальные будут ждать пол часа пока выполнится запрос?... Сомневаюсь .. остальные запросы тоже будут выполняться.. :)
Lex_! (2006-06-21 12:08:00) [36]Всем спасибо, разобрался, вроде...
:)
sniknik (2006-06-21 12:00:00) [37]> Вообще то винда вроде как многозадачна ...
> ...
неважно все, приведенный блок выполненный одним запросом другими запросами не прервется, и даже более того, будет выполнен в одной транзакции.
можеш проверить к примеру так, выполни одним блоком, типа такого
INSERT INTO Table1 (Field1) VALUES ('Test')
INSERT INTO Table1 (Field2) VALUES ('Test')
причем тут Field1 типа строка (Char(40) к примеру), а Field3 типа INT (вставляем тоже строку(!) чтобы получить ошибку). после выполнения (и ошибки) ищи в таблице в поле Field1 значение "Test", нашол? это потому, что после ошибки транзакция откатилась (самому транзакцию стартовать тут необязательно, будет автоматическая)
> запрос в TADOQuery записал, осталось вытащить значение возвращаемое ... но он почему то пустой... :о\
это знаменитая ошибка "в 17-й строке"!
Ega23 (2006-06-21 11:53:00) [38]
> Lex_! © (21.06.06 11:46) [14]
>
>
> > всё выполнится строго по очереди.
>
> Вообще то винда вроде как многозадачна .. а MSSQL это СУБД
> которая по идее может обслуживать пользователей одновременно.
> .. запросы не будут выполняться строго по очереди .. иначе
> запросы которые занимают много времени ставили бы в очередь
> всех остальных .. они выполняются псевдоодновременно ..
> немножко один немножко другой... хотя спорить... смысл :
> )
>
> запрос в TADOQuery записал, осталось вытащить значение возвращаемое
> ... но он почему то пустой... :о\
>
> ЗЫ - на хостинге для базы стоит не однопроцессорный сервер
> .... так что тут возможность одновременного выполнения думаю
> не вызывает сомнений.. :)
Ерунду вы, батенька, говорите. Не считайте разработчиков в Microsoft полными идиотами.
Lex_! (2006-06-21 11:49:00) [39]
> запрос в TADOQuery записал, осталось вытащить значение возвращаемое
> ... но он почему то пустой... :о\
Разобрался.. :)
Lex_! (2006-06-21 11:46:00) [40]
> всё выполнится строго по очереди.
Вообще то винда вроде как многозадачна .. а MSSQL это СУБД которая по идее может обслуживать пользователей одновременно... запросы не будут выполняться строго по очереди .. иначе запросы которые занимают много времени ставили бы в очередь всех остальных .. они выполняются псевдоодновременно .. немножко один немножко другой... хотя спорить... смысл :)
запрос в TADOQuery записал, осталось вытащить значение возвращаемое ... но он почему то пустой... :о\
ЗЫ - на хостинге для базы стоит не однопроцессорный сервер .... так что тут возможность одновременного выполнения думаю не вызывает сомнений.. :)