Обмануть автонумерацию.
Модератор: Andrew™
					Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
	При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
С10 + FB3. На сервере настроена автонумерация первичного ключа стандартно. В кларионовском словаре на первичном ключе автонумерация естественно не стоит. Но вот понадобилось в форме, где редактируется таблица, работать с дочерней таблицей (добавлять в неё записи, к примеру). Если только добавляется родительская запись, то добавить дочернюю не получается. Как изменить стандартный порядок не меняя политику на сервере и в словаре? Хочу, например, руками в форме добавить родительскую запись и сказать классам, что запись эта уже есть, посылай update, а не insert. Аналогично, как это бы происходило при установке в словаре автонумерации первичного ключа.
			
			
									
						We are hard at work… for you.   
			
						- ingasoftplus
 - Ветеран
 - Сообщения: 481
 - Зарегистрирован: 26 Декабрь 2006, 17:07
 - Откуда: Оттуда :)
 - Благодарил (а): 131 раз
 - Поблагодарили: 9 раз
 
- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
У меня для Firebird через стандартный драйвер ODBC использование IsIdentity и ServerAutoInc не пошло, выскакивает ошибка "Function not supported". Ну и ладно. В данном случае не очень-то и надо. Хватило бы моего ручного кода. Но вот что послать классам?
			
			
									
						We are hard at work… for you.   
			
						- Игорь Столяров
 - Ветеран движения
 - Сообщения: 8269
 - Зарегистрирован: 07 Июль 2005, 10:19
 - Откуда: г. Ростов-на-ДоМу
 - Благодарил (а): 34 раза
 - Поблагодарили: 106 раз
 
Обмануть автонумерацию.
Может быть пойти другим путем ? Если авто нумерация - это просто способ создания уникального ID записи,
то вообще ее убрать везде и заменить на GUID (или некий заведомо уникальный признак вроде Date & Clock & Random(1,999999)),
который будет формировать приложение, а далее уже использовать во всех операциях с БД. Вот и все ...
			
			
									
						то вообще ее убрать везде и заменить на GUID (или некий заведомо уникальный признак вроде Date & Clock & Random(1,999999)),
который будет формировать приложение, а далее уже использовать во всех операциях с БД. Вот и все ...
За теми, кто отстал, не возвращаться ! 
 Кодекс
			
						- 
				gopstop2007
 - Полимат
 - Сообщения: 1841
 - Зарегистрирован: 25 Март 2009, 21:55
 - Благодарил (а): 30 раз
 - Поблагодарили: 10 раз
 
Обмануть автонумерацию.
сплошное противоречие, может у базы FB взять последний autoincriminent и всем сказать о нёмkreator писал(а):Хочу, например, руками в форме добавить родительскую запись и сказать классам, что запись эта уже есть, посылай update, а не insert. Аналогично, как это бы происходило при установке в словаре автонумерации первичного ключа.
Не фанат FB, но в MYSQL это выглядит так, через LAST_INSERT_ID() в одном запросе с добавлением записи получаем Id
Код: Выделить всё
INSERT INTO `author` (`id`, `name`, `fam`, `birthday`) VALUES (NULL, 'Николай Николаевич', 'Носов', '2008-11-23');
SET @lastID := LAST_INSERT_ID();“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
			
						- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
Ну да, я так и делаю. Дальше что?gopstop2007 писал(а):Сообщение gopstop2007 » 23 Январь 2017, 17:08
kreator писал(а):
Хочу, например, руками в форме добавить родительскую запись и сказать классам, что запись эта уже есть, посылай update, а не insert. Аналогично, как это бы происходило при установке в словаре автонумерации первичного ключа.
сплошное противоречие, может у базы FB взять последний autoincriminent и всем сказать о нём
Не фанат FB, но в MYSQL это выглядит так, через LAST_INSERT_ID() в одном запросе с добавлением записи получаем Id
Код: Выделить всё
INSERT INTO `author` (`id`, `name`, `fam`, `birthday`) VALUES (NULL, 'Николай Николаевич', 'Носов', '2008-11-23');
SET @lastID := LAST_INSERT_ID();
Аналогичное есть и у FB...
Подробнее.
При вызове формы с событием InsertRecord я руками добавляю новую запись, новый ID я знаю соответственно. Если ничего не предпринимать, то программа пытается ещё сделать insert по нажатию OK. Если потом в форме request переключаю на ChangeRecord, то программа не апдейтит запись. Пока не разобрался почему. В принципе, думал всё просто - если в словаре поставить первичный ключ с автонумерацией, то всё как надо. Хотелось бы аналогично сделать.
We are hard at work… for you.   
			
						Обмануть автонумерацию.
А программа точно сделает Insert по нажатию OK? 
Последний раз, когда мне было нужно, выяснил, что вроде бы реальным добавлением записи занимается Browse, а форма по OK выполняет Update в любом случае, а на Сancel удаляет запись, если GlobalRequest = InsertRecord и ничего не делает для ChangeRecord.
Впрочем, вполне возможно, что это зависит от драйвера и параметров файла.
Собственно, вот кусочки из действующей программы
Затребовано добавление записи, запись добавили руками (никакого Browse нету), после чего сменили Request на ChangeRecord
А на обработчике кнопки OK обработали ситуацию руками 
Кстати... а нафиг нам нужна форма, почему бы не обойтись просто окошечком с кнопочками OK и Cancel ?
			
			
									
						Последний раз, когда мне было нужно, выяснил, что вроде бы реальным добавлением записи занимается Browse, а форма по OK выполняет Update в любом случае, а на Сancel удаляет запись, если GlobalRequest = InsertRecord и ничего не делает для ChangeRecord.
Впрочем, вполне возможно, что это зависит от драйвера и параметров файла.
Собственно, вот кусочки из действующей программы
Затребовано добавление записи, запись добавили руками (никакого Browse нету), после чего сменили Request на ChangeRecord
Код: Выделить всё
    
    !  ThisWIndow.Init() 
    IF ThisWindow.Request =  InsertRecord 
     !  Сами добавляем запись 
    ... 
      Pct:Ptr=...  ! Получили каким-то способом идентификатор записи 
      !  И делаем запись текущей (Важно!) 
      If Access:Pictures.Fetch(PCT:KEY_PTR)
        Message(Loc:Oi.Error,'Ошибка добавления записи оригинала')
        Return(Level:Fatal)
      End
      !  И подменили обработчик на ChangeRecord 
      OriginalRequest = ThisWindow.Request
      ThisWindow.Request = ChangeRecord
    END
Код: Выделить всё
    If Self.Request=DeleteRecord And Self.Response = RequestCompleted And Loc:DeleteFlag
       OriginalDelete(Loc:OI)
    ElsIf (OriginalRequest = InsertRecord And Self.Request = ChangeRecord And Self.Response = RequestCancelled)
       OriginalDelete(Loc:OI)
       Delete(Pictures)
    End
- 
				gopstop2007
 - Полимат
 - Сообщения: 1841
 - Зарегистрирован: 25 Март 2009, 21:55
 - Благодарил (а): 30 раз
 - Поблагодарили: 10 раз
 
Обмануть автонумерацию.
Как раз не такkreator писал(а):Ну да, я так и делаю. Дальше что?
Подробнее.
При вызове формы с событием InsertRecord я руками добавляю новую запись, новый ID я знаю соответственно. Если ничего не предпринимать, то программа пытается ещё сделать insert по нажатию OK. Если потом в форме request переключаю на ChangeRecord, то программа не апдейтит запись. Пока не разобрался почему. В принципе, думал всё просто - если в словаре поставить первичный ключ с автонумерацией, то всё как надо. Хотелось бы аналогично сделать.
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
			
						- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
И после выхода из формы нужно ещё отработать RequestCancelled?gopstop2007 писал(а):Как раз не так У меня insert через скрипт указанный выше, и открывается форма на update
Ну я всё-таки в форме добил тоже самое. При входе в форму делается Insert, новый ID получаю. При нажатии на "ОК" делается update (правда скриптом). Если идёт откат, то в методе Kill делается delete.
На самом деле надо бы разобраться в классах (думаю нужно делать по-другому). Но пока не буду, ситуация нетипичная, разовая.
We are hard at work… for you.   
			
						- 
				gopstop2007
 - Полимат
 - Сообщения: 1841
 - Зарегистрирован: 25 Март 2009, 21:55
 - Благодарил (а): 30 раз
 - Поблагодарили: 10 раз
 
Обмануть автонумерацию.
интересно посмотреть это на практике, когда куча "детишек" и коннект подвиснет
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
			
						- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
Политика форейн-ключа прописывается на сервере. Детишки удаляются там же одной транзакцией. Я просто посылаю команду удалить текущую запись данной таблицы. Если Вы об этом. А если форейн-ключ с политикой "No action", так ещё проще - пользователь сам будет удалять детишек по одной записи.gopstop2007 писал(а):интересно посмотреть это на практике, когда куча "детишек" и коннект подвиснет
We are hard at work… for you.   
			
						- 
				gopstop2007
 - Полимат
 - Сообщения: 1841
 - Зарегистрирован: 25 Март 2009, 21:55
 - Благодарил (а): 30 раз
 - Поблагодарили: 10 раз
 
Обмануть автонумерацию.
То есть можно удалить "папу" и оставить "детишек"kreator писал(а): А если форейн-ключ с политикой "No action", так ещё проще - пользователь сам будет удалять детишек по одной записи.
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
			
						- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
Извиняюсь. "Restrict" - это в рамках Клариона. То же самое в SQL стандарте - "No Action". Не готов говорить про все сервера, но в Firebird'е - "No action", и в книжке вообще про скуль - тоже "No Action". В MySQL - "Restrict"?gopstop2007 писал(а):То есть можно удалить "папу" и оставить "детишек"или может restrict ?
We are hard at work… for you.   
			
						Обмануть автонумерацию.
Restrict - это запрет на удаление папы, если у него есть дети. Надо смотреть "Cascade" или что-то в этом духе
			
			
									
						- 
				kreator
 - ✯ Ветеран ✯
 - Сообщения: 5235
 - Зарегистрирован: 28 Май 2009, 15:54
 - Откуда: Москва
 - Благодарил (а): 11 раз
 - Поблагодарили: 26 раз
 
Обмануть автонумерацию.
В SQLAnywhere через Central такая политика называется "Not Permitted", и при этом в запросе ничего не прописано специально, по умолчанию так.
			
			
									
						We are hard at work… for you.   
			
						