Обмануть автонумерацию.

ODBC

Модератор: Andrew™

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

С10 + FB3. На сервере настроена автонумерация первичного ключа стандартно. В кларионовском словаре на первичном ключе автонумерация естественно не стоит. Но вот понадобилось в форме, где редактируется таблица, работать с дочерней таблицей (добавлять в неё записи, к примеру). Если только добавляется родительская запись, то добавить дочернюю не получается. Как изменить стандартный порядок не меняя политику на сервере и в словаре? Хочу, например, руками в форме добавить родительскую запись и сказать классам, что запись эта уже есть, посылай update, а не insert. Аналогично, как это бы происходило при установке в словаре автонумерации первичного ключа.
We are hard at work… for you. :)
Аватара пользователя
ingasoftplus
Ветеран
Сообщения: 425
Зарегистрирован: 26 Декабрь 2006, 17:07
Откуда: Оттуда :)
Благодарил (а): 87 раз
Поблагодарили: 5 раз

Обмануть автонумерацию.

Сообщение ingasoftplus »

кури мануал на предмет IsIdentity и READONLY
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

У меня для Firebird через стандартный драйвер ODBC использование IsIdentity и ServerAutoInc не пошло, выскакивает ошибка "Function not supported". Ну и ладно. В данном случае не очень-то и надо. Хватило бы моего ручного кода. Но вот что послать классам?
We are hard at work… for you. :)
Аватара пользователя
Игорь Столяров
Ветеран движения
Сообщения: 7327
Зарегистрирован: 07 Июль 2005, 10:19
Откуда: г. Ростов-на-ДоМу
Благодарил (а): 13 раз
Поблагодарили: 48 раз

Обмануть автонумерацию.

Сообщение Игорь Столяров »

Может быть пойти другим путем ? Если авто нумерация - это просто способ создания уникального ID записи,
то вообще ее убрать везде и заменить на GUID (или некий заведомо уникальный признак вроде Date & Clock & Random(1,999999)),
который будет формировать приложение, а далее уже использовать во всех операциях с БД. Вот и все ...
За теми кто отстал - не возвращаться. (С) Кодекс
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

Обмануть автонумерацию.

Сообщение gopstop2007 »

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... :)
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

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. :)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Обмануть автонумерацию.

Сообщение Yufil »

А программа точно сделает Insert по нажатию OK?
Последний раз, когда мне было нужно, выяснил, что вроде бы реальным добавлением записи занимается 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
А на обработчике кнопки OK обработали ситуацию руками

Код: Выделить всё

    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
Кстати... а нафиг нам нужна форма, почему бы не обойтись просто окошечком с кнопочками OK и Cancel ?
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

Обмануть автонумерацию.

Сообщение gopstop2007 »

kreator писал(а):Ну да, я так и делаю. Дальше что?
Подробнее.
При вызове формы с событием InsertRecord я руками добавляю новую запись, новый ID я знаю соответственно. Если ничего не предпринимать, то программа пытается ещё сделать insert по нажатию OK. Если потом в форме request переключаю на ChangeRecord, то программа не апдейтит запись. Пока не разобрался почему. В принципе, думал всё просто - если в словаре поставить первичный ключ с автонумерацией, то всё как надо. Хотелось бы аналогично сделать.
Как раз не так :) У меня insert через скрипт указанный выше, и открывается форма на update :)
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

gopstop2007 писал(а):Как раз не так У меня insert через скрипт указанный выше, и открывается форма на update
И после выхода из формы нужно ещё отработать RequestCancelled?
Ну я всё-таки в форме добил тоже самое. При входе в форму делается Insert, новый ID получаю. При нажатии на "ОК" делается update (правда скриптом). Если идёт откат, то в методе Kill делается delete.
На самом деле надо бы разобраться в классах (думаю нужно делать по-другому). Но пока не буду, ситуация нетипичная, разовая.
We are hard at work… for you. :)
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

Обмануть автонумерацию.

Сообщение gopstop2007 »

kreator писал(а): Если идёт откат, то в методе Kill делается delete.
интересно посмотреть это на практике, когда куча "детишек" и коннект подвиснет :)
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

gopstop2007 писал(а):интересно посмотреть это на практике, когда куча "детишек" и коннект подвиснет :)
Политика форейн-ключа прописывается на сервере. Детишки удаляются там же одной транзакцией. Я просто посылаю команду удалить текущую запись данной таблицы. Если Вы об этом. А если форейн-ключ с политикой "No action", так ещё проще - пользователь сам будет удалять детишек по одной записи.
We are hard at work… for you. :)
gopstop2007
✯ Ветеран ✯
Сообщения: 1702
Зарегистрирован: 25 Март 2009, 21:55
Благодарил (а): 9 раз
Поблагодарили: 4 раза

Обмануть автонумерацию.

Сообщение gopstop2007 »

kreator писал(а): А если форейн-ключ с политикой "No action", так ещё проще - пользователь сам будет удалять детишек по одной записи.
То есть можно удалить "папу" и оставить "детишек" :) или может restrict ?
“Есть всего 2 типа языков: те, на которые все жалуются и те, которыми никто не пользуется.” — Бьерн Страуструп
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

gopstop2007 писал(а):То есть можно удалить "папу" и оставить "детишек" :) или может restrict ?
Извиняюсь. "Restrict" - это в рамках Клариона. То же самое в SQL стандарте - "No Action". Не готов говорить про все сервера, но в Firebird'е - "No action", и в книжке вообще про скуль - тоже "No Action". В MySQL - "Restrict"?
We are hard at work… for you. :)
Yufil
Ветеран движения
Сообщения: 1277
Зарегистрирован: 16 Май 2006, 14:34
Контактная информация:

Обмануть автонумерацию.

Сообщение Yufil »

Restrict - это запрет на удаление папы, если у него есть дети. Надо смотреть "Cascade" или что-то в этом духе
kreator
✯ Ветеран ✯
Сообщения: 4960
Зарегистрирован: 28 Май 2009, 15:54
Откуда: Москва
Благодарил (а): 6 раз
Поблагодарили: 19 раз

Обмануть автонумерацию.

Сообщение kreator »

В SQLAnywhere через Central такая политика называется "Not Permitted", и при этом в запросе ничего не прописано специально, по умолчанию так.
We are hard at work… for you. :)
Ответить