powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / генерация primary key до вставки
25 сообщений из 56, страница 2 из 3
генерация 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
25 сообщений из 56, страница 2 из 3
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / генерация primary key до вставки
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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