powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / генерация primary key до вставки
56 сообщений из 56, показаны все 3 страниц
генерация primary key до вставки
    #33032217
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
(powerBuilder 9.01 + msSqlServer 2000)
 У нас на фирме написана библиотека, аналогичная PFC.. и вот, хочу обсудить одну довольно общую проблему : ввод документа, состоящего из нескольких окон, связанных master-detail (один-ко-многим). Например, счёт-фактура может состоять из
1. заголовка
2. списка позиций
3. перечня дополнительных свойств для каждой позиции
 Пользователь должен иметь возможность сначала ввести документ целиком (или даже ввести несколько документов), и только потом -- сохранить (или отменить ввод). Собственно проблема: чтобы привязать строки подчинённых окон к главным, необходимо знать значение Primary Key главного окна (и это до сохранения!). У нас на фирме было (давно) принято такое решение: отказаться от автогенерации Primary Key и генерировать значение уникального поля до вставки в таблицу (пересечения с данными, вводимыми другими пользователями, исключаются использованием при генерации функции SQL-сервера, возвращающей номер соединения, @@uuid) , а после ввода уже спокойно сохранять. Коллизии такой генерации PK пока (за три-четыре года эксплуатации) не встречались.

 Вопрос:
1. какие ещё алгоритмы ввода многооконных документов предложите?
2. как это реализовано в PFC (в этой библиотеке тоже ведь есть службы связи окон (спрашиваю потому, что сам я ещё не пользовался этой библиотекой)
3. какие есть недостатки предложенного здесь метода ввода документов -- с помощью генерации первичного ключа до вставки? (подробности генерации там же .

спасибо!
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032263
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может это и неправильно, но последние десятилетия мои приложения, в основном, получают ID до формирования новой записи на клиенте.

На псевдокоде - of_GetId ()
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032266
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sorry, не туда нажал

Продолжу

На псевдоколе:
Код: plaintext
1.
2.
3.
4.
decimal{ 0 } ld_ID 
long ll_row
ld_ID = of_GetId()
ll_row = InsertRow()
SetItem (ll_Row, "ID_COL", ld_ID)
Если надо обеспечить связь мастер-деталь, то полученный ID вставляется в соответствующее поле детали.

Вот и все, собственно.

Да, чуть не забыл. Для MS SQL был разработан механизм, реализующий аналог сиквенса в Oracle.

Разумеется, в БД уникальность первичных ключей обеспечивается по всей БД, т.е. используется только один сиквенс, кроме каких-то специальных случаев
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032268
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все-таки забыл :-)

Разумеется, что функция of_GetId() обращается за ID к серверу.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032381
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно завести еще одно поле для связи в DataWindow, а поле PK не трогать. Внутри DataWindow осуществлять связь master-detail по значениям второго поля, используя для новых записей отрицательную нумерацию (в базу естественно ничего не сохраняя из этого второго поля).
А при SELECT'е заполнять его значениями из PK, в этом случае никаких коллизий произойти просто не может.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032592
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гм, у нас проблема была решена другим способом.
При открытии окна документа в базу уже добавляется запись со всеми начальными значениями и сгенеренным идентификатором. Единственное запись помегена как "неактуальная". Соответственно при вставке перечня идентификатор известен, а при нажатии на клиенте кнопки OK идет обновление существующей записи введенными данными и изменение состояния записи на актуальное. Если "OK" не нажата, то в базе остается "паразитная" неактуальная запись.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33032600
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
Локшин МаркМожно завести еще одно поле для связи в DataWindow, а поле PK не трогать. Внутри DataWindow осуществлять связь master-detail по значениям второго поля, используя для новых записей отрицательную нумерацию (в базу естественно ничего не сохраняя из этого второго поля).
А при SELECT'е заполнять его значениями из PK, в этом случае никаких коллизий произойти просто не может.
Почти так же. Новых полей не использую - пишу отрицательные значения как раз в поле PK - а в событии UpdateStart() отрицательные значения заменяю на уникальные из SEQUENS-последовательности (Oracle)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033155
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gzПочти так же. Новых полей не использую - пишу отрицательные значения как раз в поле PK - а в событии UpdateStart() отрицательные значения заменяю на уникальные из SEQUENS-последовательности (Oracle)
Можно и так, но шанс словить ошибку при кодировании таким образом выше.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033165
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
понятно, спасибо за примеры.
 а чем так генерация первичного ключа на сервере не нравится? Наши утверждают (я сам не пробовал), что если пользоваться генерацией ключа на сервере (сиквенсы, identity и что там в Sybase-вский СУБД?), то может измениться порядок строк после insert\retrieve, правда, я не понял, почему.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033190
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
Локшин МаркМожно и так, но шанс словить ошибку при кодировании таким образом выше.
А каким образом ? Сколько лет ловим, пока сетка пустая. Если перестраховываться, то уж в меру ...
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033236
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gzА каким образом ? Сколько лет ловим, пока сетка пустая. Если перестраховываться, то уж в меру ...
Допустим нужно будет откатиться, тогда это нужно тоже нужно учитывать при кодировании. Имееются ввиду ошибки программиста при реализации механизма на PB.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033279
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
Локшин МаркДопустим нужно будет откатиться, тогда это нужно тоже нужно учитывать при кодировании. Имееются ввиду ошибки программиста при реализации механизма на PB.
Что-й-то плохо соображаю. Вроде бы, и при откатах работает. Может быть, имеете ввиду просто "кривые ручки" программиста ?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033282
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyпонятно, спасибо за примеры.
 а чем так генерация первичного ключа на сервере не нравится? Наши утверждают (я сам не пробовал), что если пользоваться генерацией ключа на сервере (сиквенсы, identity и что там в Sybase-вский СУБД?), то может измениться порядок строк после insert\retrieve, правда, я не понял, почему.
Смотря в какой Sybase СУБД. Если в ASA 9, то просто пишем в клиенте <SELECT GET_IDENTITY('TableName') >, получаем собственный зарезервированный ID, автоматом увеличивая инкримент в таблице без организации транзакции и вообще больше ни о чем не думаем :)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033288
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк gzА каким образом ? Сколько лет ловим, пока сетка пустая. Если перестраховываться, то уж в меру ...
Допустим нужно будет откатиться, тогда это нужно тоже нужно учитывать при кодировании. Имееются ввиду ошибки программиста при реализации механизма на PB.
Откаты на SEQUENS и IDENTITY не влияют, так что ошибок не будет.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033309
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS Откаты на SEQUENS и IDENTITY не влияют, так что ошибок не будет.
Не про те ошибки идет речь.
gzМожет быть, имеете ввиду просто "кривые ручки" программиста ?
Да, именно это я и пытался сказать :) Больше нюансов в реализации, а сл-но больше вероятность ошибки (программиста).
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033338
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
Локшин Марк gzМожет быть, имеете ввиду просто "кривые ручки" программиста ?
Да, именно это я и пытался сказать :) Больше нюансов в реализации, а сл-но больше вероятность ошибки (программиста).
Как раз добавление в SELECT дополнительного поля (не поля базы данных + специальным образом заполняемого) и дает дополнительные навороты.
Хотя, чего мы спорим ? У нас реализация совпала процентов на 90-95. Значит, "верным путем идем, товарищи"
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033480
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyпонятно, спасибо за примеры.
 а чем так генерация первичного ключа на сервере не нравится? Наши утверждают (я сам не пробовал), что если пользоваться генерацией ключа на сервере (сиквенсы, identity и что там в Sybase-вский СУБД?), то может измениться порядок строк после insert\retrieve, правда, я не понял, почему.Гм... Не понял. Порядок строк обеспечивается конструкцией ORDER BY в запросе или сортировкой на клиенте.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33033604
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
PL99Гм... Не понял. Порядок строк обеспечивается конструкцией ORDER BY в запросе или сортировкой на клиенте.
Случай из жизни. Армия. Вон, розетка - какой ток течет - постоянный или переменный ? Ответ - постоянный. Вышел товарищ. А ты, меня спрашивают - понял ? Ну, говорю, постоянный - прямая, а переменный - синусоида. Нет, говорят, вышедший товарищ имел ввиду, что постоянный - это 220 вольт не больше и не меньше.
Так что PL99, не забивай себе голову, что имел ввиду товарищ
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33034090
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я имел ввиду порядок строк в таблице без order'а. то есть, добавили несколько новых записей, визуально они появились в конце datawindow, а после retrieve (=select col1, col2, ... from table1 where parent_id=xxx) -- некоторые записи могут своё место в DW изменить.. но я это не видел, передаю лишь слова.. и не могу понять, почему, ведь нет сортировки даже по первичному ключу..
 Хотя, на мой взгляд, причины генерации первичного ключа другие (нежели простое соблюдение порядка строк в DW):
1. возможность заполнять несколько master'ов с detail'ами внутри (привязка строк в detail'е до сохранения master'а).
2. на сервере средства работы с identity (автогенератором числового первичного ключа) не понравились главному разработчику (напр., потому что реализованы кривова-то или, там, требуют вызова хранимой процедуры)

 Как выяснилось, у нас именно второй случай. а при вводе нового master'а происходит тихое сохранение введённых dateil'ов для строки, потерявшей фокус ввода.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33034212
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyя имел ввиду порядок строк в таблице без order'а. то есть, добавили несколько новых записей, визуально они появились в конце datawindow, а после retrieve (=select col1, col2, ... from table1 where parent_id=xxx) -- некоторые записи могут своё место в DW изменить.. но я это не видел, передаю лишь слова.. и не могу понять, почему, ведь нет сортировки даже по первичному ключу..
Для любой реляционной операции порядок следования кортежей отношений никогда не определен.
В конкретном частном случае записи по запросу
Код: plaintext
select col1, col2, ... from table1 where parent_id=xxx
будут возвращены в порядке следования ссылок на строки table1 в parent_id.
Или в порядке физического местоположения записей записей в таблице table1 (в зависимости от селективности условия parent_id).
Но это никто и никому не обязан. Допустим, все может измениться от числа процессоров в системе
savosin_sergey на сервере средства работы с identity (автогенератором числового первичного ключа) не понравились главному разработчику
И какие же альтернативы?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33034220
gz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
gz
Гость
to savosin_sergey
Выборка строк "без ордера". В общем-то, реляционная база не гарантирует последовательность вывода строк в порядке их ввода. Хотя некоторое подобие порядка при полупустой базе может и наблюдаться.
Вопрос по сохранению сортировки при повторном вызове формы имеет иногда принципиальное значение. Можно, конечно, использовать уникальный ключ для сортировки (помучаться при этом), но лучше добавить просто поле "номер строки" в таблицу.

"Тихое сохранение" - это что-то новое. Какие-то нехорошие ассоциации. Конечно, от ошибок никто не застрахован, однако, если таких ситуаций много, бежать надо скорее от таких разработчиков.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035409
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркИ какие же альтернативы?
Вот алгоритм генерации нового уникального значения, применяемый у нас (в классах, работающих со связанными DW).. Правда, эта функция немного переделанная (работает лишь с одной таблицей bu_extravalues , но, жумаю, смысл будет ясен.. Переменные gnv_appl.i_step и gnv_appl.i_spid заполняются при запуске приложения.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
/***************************************************
 функция возвращает новый ПервичныйКлюч            *
для таблицы bu_extraValues со структурой           *
create table bu_extraValues (bu_vlsid int not null)*
gnv_appl.i_step -- переменная, раза в три больше   *
 максимального числа пользователей (шаг значений   *
 первичного ключа)                                 *
gnv_appl.i_spid -- номер коннекта к БД: @@sp_id на *
 microsoft sql server                              */
long du_id, l_mx

/*запрос максимального значения первичного ключа*/
select isnull(max(bu_vlsid), 1 ) into :l_mx from bu_extravalues;
if sqlca.sqlcode<> 0  then
	return - 1 
end if

/*генерация нового значения ПК*/
du_id = l_mx / gnv_appl.i_step

if du_id * gnv_appl.i_step + gnv_appl.i_spid > l_mx then
	return  du_id * gnv_appl.i_step + gnv_appl.i_spid
else
	return  ( du_id + 1  ) * gnv_appl.i_step + gnv_appl.i_spid
end if
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035508
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторВот алгоритм генерации нового уникального значения, применяемый у нас (в классах, работающих со связанными DW).. Правда, эта функция немного переделанная (работает лишь с одной таблицей bu_extravalues, но, жумаю, смысл будет ясен.. Переменные gnv_appl.i_step и gnv_appl.i_spid заполняются при запуске приложения.
И в чем же преимущества? Абсолютно не гарантируется никакой уникальности сгенерированных значений. Что, у одного пользователя не может быть несколько connect'ов к базе? Что достигается в результате такого извращения? Это если у вас главный разработчик такое пишет...
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035612
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЧто, у одного пользователя не может быть несколько connect'ов к базе? Что достигается в результате такого извращения?
Номер коннекшена (через который будет производиться insert) всегда уникальен, среди всех подключённых пользователей. У одного пользователя можут быт два коннекта, но с разными @@spid. Так что коллизий не наблюдается (уже больше трёх лет фурычит в минфине, там пользователей около 100, данные вводят человек 5)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035637
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
другими словами, у SQLCA всегда один коннект, и у него есть уникальный номер на сервере (среди всез поключений к серверу). Как этот номер узнать в oracle или в sybase-вских СУБД я не знаю. в MsSqlServer это переменная @@spid
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035645
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyНомер коннекшена (через который будет производиться insert) всегда уникальен, среди всех подключённых пользователей. У одного пользователя можут быт два коннекта, но с разными @@spid.
А если пользователь по два приложения запустит?
savosin_sergeyТак что коллизий не наблюдается
Это главное достоинство метода?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035680
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот наша процедура для MS/Syabse без всяких наворотов;)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create procedure dbo.ap_getid @id numeric out    
as     
declare @site_id numeric( 2 , 0 )
begin     
   select @site_id=id from t_sites where is_local= 1      
   if @@error!= 0  return    
   if @site_id is null begin     
      raiserror  40000  'Неизвестна площадка'     
      return     
   end      
   insert t_idgenerator (site_id) values (@site_id)     
   if @@error!= 0  return     
   select @id = @@identity + @site_id* 10000000000000000     
end

Таблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035699
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EstetsВот наша процедура для MS/Syabse без всяких наворотов;)
...
Таблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.Вот нечто подобное и я имел ввиду
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33035779
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
EstetsТаблица t_idgenerator имеет IDENTITY поле.
Таблица t_sites используется для разделения диапазона по разным серверам.
А почему не использовать для этого identity seed?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036034
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Исторически сложилось ;)
Вообще-то планировалось размножение баз дампами с изменением номера локального сервера.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036087
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркА если пользователь по два приложения запустит?
Будет два SQLCA и два разных номера соединений
Локшин МаркЭто главное достоинство метода?
Это необходимое условие работы метода.

2 Estets:
Estets
Код: plaintext
select @id = @@identity + @site_id* 10000000000000000 
какой же длины у вас ключевые поля? если шаг между серверами=10^17
Код: plaintext
select @site_id=id from t_sites where is_local= 1 
что такое is_local=1? и где название таблицы? или у вас все таблицы получают "сквозной" идентификатор?

Локшин МаркА почему не использовать для этого identity seed?
Да на самом деле (это относится к MsSqlServer2000) можно использовать признак identity у колонки в таблице (чтобы она автоматически увеличивала значение) + функцию SCOPE_IDENTITY() -- она возвращает последнее значение identity-колонки в таблице, в которой произощёл последний insert..

я на этом сервере на форуме, посвящённом MsSqlServer-у читал всякие предложения по генерации уникальных значений.. там тоже было предложение с использованием временной таблицы и обсуждались какие-то проблемы..
/topic/103151&hl=
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036169
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyкакой же длины у вас ключевые поля? если шаг между серверами=10^17а если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036171
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А GUID кстати никто не пробовал использовать в качестве PK?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036214
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyБудет два SQLCA и два разных номера соединений
А когда запустят по 4 копии, вот тут-то диапазоны и перекроются.
savosin_sergeyДа на самом деле (это относится к MsSqlServer2000) можно использовать признак identity у колонки в таблице (чтобы она автоматически увеличивала значение) + функцию SCOPE_IDENTITY() -- она возвращает последнее значение identity-колонки в таблице, в которой произощёл последний insert.
А чем более ранние версии SQL сервера не угодили. Вы описали принцип заполнения переменной @@IDENTITY, а она и раньше была.
savosin_sergeyЭто необходимое условие работы метода.
А в чем его преимущества?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036253
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЗоринАндрейА GUID кстати никто не пробовал использовать в качестве PK?Да, пробовал два раза (в двух проектах). Работает :-)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036265
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин Марк savosin_sergeyЭто необходимое условие работы метода.А в чем его преимущества?Старший приказал (с) :-)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036326
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PL99 ЗоринАндрейА GUID кстати никто не пробовал использовать в качестве PK?Да, пробовал два раза (в двух проектах). Работает :-)
Ну их эти GUID ... попробовали в одном новом разрабатывающемся проекте ASA, потом плюнули, домен на unsigned int перевели с GLOBAL AUTOINCREMENT и решили больше никогда не связываться. Из реальных проблем - неоправданно большой размер PK и FK, неудобство ручного написания запросов (без Copy-Paste никуда), из за "скачущих" значений GUID неоптимальное хранение веток индексов в БД, из за этого проседания на join-ах при выборках, плюс еще кое какие мелкие баги самой ASA при работе с GUID, которые я им заявил, но исправить они еще не успели (например невозможность подключения таблицы удаленного сервера ASA, в которой есть GUID или выполнение SELECT * INTO Table). Единственное, где не было нареканий - так как использовалась ASA 9.0.2, то PB видел их как string и проблем в клиентской части не было. Так что я зарекся от их использования, GLOBAL AUTOINCREMENT на целых числах гораздо приятнее и привычнее получается.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036466
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergey

2 Estets:
Estetsselect @id = @@identity + @site_id*10000000000000000
какой же длины у вас ключевые поля? если шаг между серверами=10^17
select @site_id=id from t_sites where is_local=1
что такое is_local=1? и где название таблицы? или у вас все таблицы получают "сквозной" идентификатор?

Идентификатор numeric(18,0), Две цифры под сервер, 16 под Increment
SSNNNNNNNNNNNNNNNN

Таблица t_sites примерно такая:
id srv_name is_local
1 'Server1' 1
1 'Server2' 0
1 'Server3' 0

Только в реальности данный механизм не понадобился ;-( Хотя были планы настроить репликацию.

Угумс в этом есть своя прелесть, в какой бы таблице не находился документ, можно определить его тип по глобальному идентификатору.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036849
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркА когда запустят по 4 копии, вот тут-то диапазоны и перекроются.
Да, если шаг=300 (в примере gnv_appl.i_step) и если все 100 пользователей запустят по 3-4 копии, то накроется. Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)
Локшин МаркА чем более ранние версии SQL сервера не угодили. Вы описали принцип заполнения переменной @@IDENTITY, а она и раньше была.
 Так один пользователь считал @@identity (до сохранения), потом другой считал @@identity -- произойдёт совпадение. Можно считывать лишь после сохранения -- с тем, чтобы передать его подчинённым detail'ам..
Локшин МаркА в чем его преимущества?
Другое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..
 У нас "ведущий" программер решил уникальное поле генерить на клиенте -- вот и я предложил для обсуждения его метод.
 На соседнем форуме (ссылка на него в начале этой темы) мне совсем другой метод предложили для ввода связанных таблиц..
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036935
Фотография PL99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyДругое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..
Да можно ничего не придумывать, а взять готовое
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33036980
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 PL99: спасибо.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037071
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergey Так один пользователь считал @@identity (до сохранения), потом другой считал @@identity -- произойдёт совпадение. Можно считывать лишь после сохранения -- с тем, чтобы передать его подчинённым detail'ам..
За каким извините хреном считывать identity до сохранения? Оно вообще неизвестно что вернет.
savosin_sergeyДругое преимущество: если использовать автоинкремент, то после сохранения в DW не будет значения уникального поля -- для этого надо сделать retrieve. Если записей много в таблице, то делать retrieve после каждого insert'а -- долгова-то. В этом случае придётся считывать @@identity из базы и присваивать полю DW.. ну или ещё что-нибудь придумывать..
Пользователь редко вводит больше 10 записей не сохраняясь. Вы думаете 10 SELECT @@identity сильно просадят производительность?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037087
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergey Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)
Т.е. ваша система расчитана на то, чтобы проработать чуть больше 2-х лет?
Кроме того, вы размениваете тривиальный запрос к переменной connect-а (@@identity) при сохранении (которое не всегда будет), на гарантированный запрос при добавлении строки в DataWindow к таблце, что гораздо более затратно.
Какие еще преимущества, как вам кажется, есть у этого метода? (пока видны одни недостатки).
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037599
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Локшин Марк:
авторЗа каким извините хреном считывать identity до сохранения? Оно вообще неизвестно что вернет.
Уважаемый Марк, ну а когда его, @@identity считывать? не после же сохранения? или я что-то не понимаю.. есть операция dw.update(boolean, boolean), есть операция select @@identity into :iid;.. даже если select @@identity повесить в event updatestart() -- разве гарантируется, что действия в updatestart() выполнятся в той же транзакции, что и реальное сохранение DW?

авторПользователь редко вводит больше 10 записей не сохраняясь. Вы думаете 10 SELECT @@identity сильно просадят производительность?
я имел ввиду retrieve DW целиком -- чтобы в неё, в DW, закачались значения автоинкрементного столбца (после dw.update()). И если в таблице много строк, то по-идее, retrieve будет проходить некотрое заметное время.. (даже если он один, общий для всех введённых записей)

авторТ.е. ваша система расчитана на то, чтобы проработать чуть больше 2-х лет?
Пример с 90млнами строк в год -- это таблица проводок, которая раз в год полностью чистится (остатки в сальдо)(если я не переборщил с числом строк). Таких большие таблице у нас в системе редко встречаются.. но если есть, то можно тип первичного ключа заменить на numeric(20)..

авторКроме того, вы размениваете тривиальный запрос к переменной connect-а (@@identity) при сохранении (которое не всегда будет), на гарантированный запрос при добавлении строки в DataWindow к таблце, что гораздо более затратно.
Извините, не понял.. в любом случае надо строку к DW добавлять (вопрос лишь в заполнении или в не заполнении поля с первичным ключём.). И в любом случае после нажатия "Сохранить" придётся делать update. Где гарантированный запрос ?

спасибо!
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037626
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
яДа, если шаг=300 (в примере gnv_appl.i_step) и если все 100 пользователей запустят по 3-4 копии, то накроется. Хотя можно увеличить шаг до 1000... всё равно если для первичного ключа использовать integer, то 2 млрда / 1000 = 200 000 000 -- нашу систему это устраивает (максимальное наблюдаемое число проводок около 90 млн за год)
чё-то меня дважды проглючило: 2 млрда/300 = около 6.6 млн записей. (может вместить в себя поле integer, если в него записывать значение с шагом 300).
 Второй глюк -- я видел таблицу самое большое в 9 млн строк. Для неё действительно надо либо последовательно генерить значения, либо использовать numeric(18). С другой стороны, указанная таблица не вводится в вручную пользователями -- это результат расчёта ХП, и для неё сойдёт обычный автоинкремент..

ЗоринАндрейа если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить. Откуда такая информация?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037686
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyУважаемый Марк, ну а когда его, @@identity считывать? не после же сохранения?
именно после
savosin_sergeyили я что-то не понимаю..
безусловно, при том, вам это уже несколько раз объясняли (в т.ч. в соседнем форуме).
savosin_sergeyесть операция dw.update(boolean, boolean), есть операция select @@identity into :iid;.. даже если select @@identity повесить в event updatestart() -- разве гарантируется, что действия в updatestart() выполнятся в той же транзакции, что и реальное сохранение DW?
Да гарантируется, если у вас там на обработке очередная чушь не написана. Транзакциями в PB управляете Вы сами. Если транзакция начата, то пока вы не сделаете commit или rollback все будет в рамках этой транзакции.
Кроме того, если указать для таблицы identity column, то вообще ничего делать не нужно! После вставки каждой строки PB сам запросит значение автоинкремента и запишет его в нужную колонку DW.
savosin_sergeyя имел ввиду retrieve DW целиком -- чтобы в неё, в DW, закачались значения автоинкрементного столбца (после dw.update()). И если в таблице много строк, то по-идее, retrieve будет проходить некотрое заметное время.. (даже если он один, общий для всех введённых записей)
И для чего после сохранения делать retrieve DW целиком, чтобы получить значения автоинкрементов? Их не так получают.
savosin_sergeyИзвините, не понял.. в любом случае надо строку к DW добавлять (вопрос лишь в заполнении или в не заполнении поля с первичным ключём.). И в любом случае после нажатия "Сохранить" придётся делать update. Где гарантированный запрос?
Следите внимательно, объясняю последний раз.
При добавлении пользователем строки в DataWindow вам всегда необходимо будет исполнить запрос типа select max(field) from table
Вам это будет необходимо сдезать до записи в таблицу . Этот запрос необходимо будет исполнять всегда при вставке, в отличае от select @@identity, который нужно исполнять только после успешного insert (а еще пользователь может нажать "отмена"), и второй запрос занимает в сотни раз меньше ресурсов, чем первый.
Так что Вам тоже необходимо два запроса к серверу для вставки строки. Первый на select, второй на insert. В случае автоинкремента - первый на insert, второй на select.
Понятно?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037760
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторесли у вас там на обработке очередная чушь не написана
Товарищ, воздержитесь от грубых выражений. Я на вас не наезжал.
авторПри добавлении пользователем строки в DataWindow вам всегда необходимо будет исполнить запрос типа select max(field) from table
Это сделано на updatestart() -- то есть, только при сохранении ввода пользователем.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037845
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyТоварищ, воздержитесь от грубых выражений. Я на вас не наезжал.
То, каким образом у вас автоинкрементное поле вычисляется иначе как чушью назвать сложно. Ну не привели вы ни одного аргумента, почему так сделано. Если все приложение написано в том же духе, то может быть и на сохранение там свой "улучшенный" алгоритм написан.
savosin_sergeyЭто сделано на updatestart() -- то есть, только при сохранении ввода пользователем.
Хорошо, тогда запросов получится столько же. Но в этом случаее вообще не понятно, зачем Вам значение ключа до сохранения, если все-равно оно вычисляется непосредственно перед процедурой сохранения. Т.е. два документа шапка-подвал в одном окне не сохраняя у вас ввести нельзя?
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33037956
Estets
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторЗоринАндрей
а если еще вспомнить что PB воспринимает не более 18 значащих разрядов, то вообще засада. и на десяток site_id может не хватить.

savosin_sergey
Откуда такая информация?

Гм из горького опыта. На самом деле PB (по крайней мере 6.5, хотя не думаю что в старших версиях что-то изменилось) воспринимает только 17 значащих разрядов.
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33039141
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркКроме того, если указать для таблицы identity column, то вообще ничего делать не нужно! После вставки каждой строки PB сам запросит значение автоинкремента и запишет его в нужную колонку DW.
Что-то у меня не получилось. Сервер msSqlServer2000 (personal), таблица примерно такая:
Код: plaintext
create table bu_test (id int identity, data varchar( 50 ))
Делаю на ней DW (grid), указываю identity column = id. После update() в соответствующей колонке значение поля id не появляется (для этого надо делать retrieve() ). Даже на updateend() getItemNumber(getrow(), 'id') возвращает ноль (getRow() я проверял -- возвращает правильную строку). То ли не в том буфере искал, то ли настроил я что-то не так.

Коннекты проверялись такие:
1. DBMS="OLE DB", DBParm = "PROVIDER='SQLOLEDB'..."
2. DBMS = "MSS Microsoft SQL Server", DBParm = ""

Поле id я пробовал указывать в Updateble Columns, пробовал не указывать.. короче, надо не гадать, а знать, как это делать, чтобы работало!

В pbodb90.ini в разделе [MS_SQLSERVER_SYNTAX] указано GetIdentity='Select @@identity' .



В обоих случая нету значения identity-поля, как это утверждалось здесь . Хотя бы из-за этого генерация id-поля вручную имеет право на жизнь, как работающий вариант. Альтернатива считыванию @@identity до сохранения..
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33039448
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понятия не имею, что Вы там сделали, но если создать DataWindow на основе этой таблицы по запросу
Код: plaintext
SELECT bu_test.id,bu_test.data FROM bu_test 

Указать Allow Updates, выбрать таблиуц bu_test, в updateable columns выбрать data, в unique и identity - id, то зайдя на вкладку preview, внеся пару строчек и сохраня в поле ID мы получим значения автоинкремента. И в программе точно также. Какая версия PB?
savosin_sergey В обоих случая нету значения identity-поля, как это утверждалось здесь.
К вашему случаю это не имеет ровно никакого отношения.
savosin_sergey Хотя бы из-за этого генерация id-поля вручную имеет право на жизнь, как работающий вариант.Но уж точно не Ваш вариант.
savosin_sergey Альтернатива считыванию @@identity до сохранения..СКОЛЬКО РАЗ МОЖНО ГОВОРИТЬ, ЧТО @@identity НУЖНО СЧИТЫВАТЬ ПОСЛЕ СОХРАНЕНИЯ!!!
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33040275
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но уж точно не Ваш вариант.

Локшин Марк savosin_sergeyАльтернатива считыванию @@identity до сохранения..
СКОЛЬКО РАЗ МОЖНО ГОВОРИТЬ, ЧТО @@identity НУЖНО СЧИТЫВАТЬ ПОСЛЕ СОХРАНЕНИЯ!!!
Да, я ошибся. Хотя имел ввиду "после созранения", полностью в вами, Марк согласен. Всязи с этим хотел бы обсудить такой вариант:
- работают два пользователя с одним документом (допустим, состоящим из одной таблицы tbl1 (id int identity, data varchar(50))
- первый пользователь добавляет строку, заполянет жмёт сохранить
- при этом второй пользователь в этом же документе добавляет строку, жмёт сохранить
- первый пользователь после своего удачного сохранения считывает @@identity (например, на updateend()) -- и получает id для другой записи (записи, вставленной вторым пользователем)
=>возможен конфликт (смотрим сюда)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33040291
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Локшин МаркУказать Allow Updates, выбрать таблиуц bu_test, в updateable columns выбрать data, в unique и identity - id, то зайдя на вкладку preview, внеся пару строчек и сохраня в поле ID мы получим значения автоинкремента. И в программе точно также. Какая версия PB?
pb9.01 build 7275
действительно, в dw-painter'е работает.. надо будет простое окно потестить, а то все мои тесты проходят не на обычных DW-control'ах, а на специальных наследниках (технология фирмы. аналог PFC)
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33040316
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergeyНо уж точно не Ваш вариант.

Локшин Марк savosin_sergeyАльтернатива считыванию @@identity до сохранения..
СКОЛЬКО РАЗ МОЖНО ГОВОРИТЬ, ЧТО @@identity НУЖНО СЧИТЫВАТЬ ПОСЛЕ СОХРАНЕНИЯ!!!
Да, я ошибся. Хотя имел ввиду "после созранения", полностью в вами, Марк согласен. Всязи с этим хотел бы обсудить такой вариант:
- работают два пользователя с одним документом (допустим, состоящим из одной таблицы tbl1 (id int identity, data varchar(50))
- первый пользователь добавляет строку, заполянет жмёт сохранить
- при этом второй пользователь в этом же документе добавляет строку, жмёт сохранить
- первый пользователь после своего удачного сохранения считывает @@identity (например, на updateend()) -- и получает id для другой записи (записи, вставленной вторым пользователем)
=>возможен конфликт (смотрим сюда)
@@IDENTITY вообще то сессионная переменная, то есть для каждой сессии в ней будет значение id последней вставленной записи в сессии. Поэтому о каких конфликтах может идти речь, лично я не понимаю. У Вас что - 2 программы через одну сессию что ли работают ???
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33040394
Локшин Марк
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
savosin_sergey- работают два пользователя с одним документом (допустим, состоящим из одной таблицы tbl1 (id int identity, data varchar(50))
- первый пользователь добавляет строку, заполянет жмёт сохранить
- при этом второй пользователь в этом же документе добавляет строку, жмёт сохранить
- первый пользователь после своего удачного сохранения считывает @@identity (например, на updateend()) -- и получает id для другой записи (записи, вставленной вторым пользователем)
=>возможен конфликт (смотрим сюда)
Гм. Там я говорил про кривость реализации получения значения автоинкрементного поля в PowerBuilder'е. Но они это осознали
Локшин МаркСм. help по AtAtIdentity DBParm parameter
правда только к 7 версии PB.
В случае его задания ситуация, подобная приведенной в ссылке принципиально невозможна.
savosin_sergeyдействительно, в dw-painter'е работает.. надо будет простое окно потестить, а то все мои тесты проходят не на обычных DW-control'ах, а на специальных наследниках (технология фирмы. аналог PFC)
О чем я и говорил...
...
Рейтинг: 0 / 0
генерация primary key до вставки
    #33040470
Фотография savosin_sergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS@@IDENTITY вообще то сессионная переменная, то есть для каждой сессии в ней будет значение id последней вставленной записи в сессии.

Действительно! спасибо. просто я невнимательно прочитал документацию. SCOPE_IDENTITY тоже ничего

msSqlServer2k online books@@IDENTITY and SCOPE_IDENTITY will return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.

IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the identity value generated for a specific table in any session and any scope.
...
Рейтинг: 0 / 0
56 сообщений из 56, показаны все 3 страниц
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / генерация primary key до вставки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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