Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.07;
Скачать: CL | DM;

Вниз

Добавление новой записи - Invalid variant type convertion   Найти похожие ветки 

 
reticon ©   (2005-07-01 14:21) [0]

Работаю с таблицей через IBQuery. Если в таблице уже есть хотя бы одна запись, то добавление, редактирование и удаление других новых записей проходит нормально. Если же удалить все записи из таблицы, а потом попытаться довавить новую, то получаем Invalid variant type convertion. Где грабли?


 
Sergey13 ©   (2005-07-01 14:28) [1]

В тригере (или в проге) наверное новый ИДшник максом ищется. От NULL +1 и дает подобное.


 
Stakan ©   (2005-07-01 14:43) [2]

Грабли в твоём коде, в том месте где ты добавляешь запись.


 
reticon ©   (2005-07-01 14:45) [3]

да, ID генерится в триггере:

SET TERM ^;
CREATE TRIGGER TBI_CD FOR CD
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
 NEW.ID = GEN_ID(CD_ID_GEN, 1);
END;^

а вот что там максоам ищется и про NULL + 1 я не совсем тебя понял :)


 
reticon ©   (2005-07-01 14:48) [4]

Тю, кажется нашел в чем причина...

При добавлении записи у меня сначала идет вот что:
IBQuery1.Params[0].asInteger := MainForm.IBStoredProc1.Params[0].asInteger;

где ХП реализована в виде

CREATE PROCEDURE GET_NEW_CD_ID
RETURNS (CD_ID INTEGER)
AS
BEGIN
 CD_ID = GEN_ID(CD_ID_GEN, 1);
END;^

Неужели отсюда грабля?


 
Sergey13 ©   (2005-07-01 14:58) [5]

2[3] reticon ©   (01.07.05 14:45)
>а вот что там максоам ищется и про NULL + 1 я не совсем тебя понял :)
Я просто предположил что новый ИД находится как max(ID)+1. Соответственно на пустой таблице и получишь NULL + 1. Не так, значит мое предположение не верно.

2[4] reticon ©   (01.07.05 14:48)
А зачем тебе процедура эта? Как она к таблице относится?


 
Johnmen ©   (2005-07-01 14:58) [6]

Занятно. Сам написал и сам не понимаешь что...
Два разА дернуть генератор - это зачем ?
:)))


 
reticon ©   (2005-07-01 15:03) [7]

ХП нужна просто для получения ID, или можно обойтись без нее?


 
Sergey13 ©   (2005-07-01 15:08) [8]

2 [7] reticon ©   (01.07.05 15:03)
В таблицу вставится не то что ты получил в процедуре.


 
Stakan ©   (2005-07-01 15:17) [9]


> ХП нужна просто для получения ID, или можно обойтись
> без нее?

Так ты - же в триггере ID получаешь, оставь что - нибудь одно, ИМХО лучше ХП


 
msguns ©   (2005-07-01 15:29) [10]

Если триггер во всех случаях сам вставляет новый ID, на кой его предварительно определять, с помощью ХП или без.
Либо вставить в триггер проверку на NULL, либо не солить соль.


 
Danilka ©   (2005-07-01 15:30) [11]

Stakan ©   (01.07.05 15:17)

ИМХО лучше ХП


На твое имхо есть мое, которое категорически несогласное!


 
Stakan ©   (2005-07-01 15:31) [12]


> На твое имхо есть мое, которое категорически
> несогласное

Обоснуй чем плоха ХП


 
Sergey13 ©   (2005-07-01 15:34) [13]

2[12] Stakan ©   (01.07.05 15:31)
А чем же она хороша?
(с)
8-)


 
reticon ©   (2005-07-01 15:36) [14]

понятно, разобрался, спасибо :)
для ID оставлю триггер


 
Stakan ©   (2005-07-01 15:38) [15]

Sergey13 ©   (01.07.05 15:34) [13]
А тем что значение ID которое она вернула у тебя под рукой, и ты его можешь использовать. Как правило, в сложных системах после добавления записи требуется выполнить ещё ряд действий с этой записью (например,  зарегистрировать добавление). Если программа простая, то можно обойтись и триггером, но лучше везде использовать один подход.


 
Danilka ©   (2005-07-01 15:43) [16]

Stakan ©   (01.07.05 15:38)


Хм. Неужели в ИБ нет возможности узнать значение после вставки? Какого-нибудь returning?


 
Danilka ©   (2005-07-01 15:43) [17]

Stakan ©   (01.07.05 15:31)

> На твое имхо есть мое, которое категорически
> несогласное

Обоснуй чем плоха ХП


Хотя-бы тем, что я (или любой другой воинствующий ламер :) ) могу зайти в твою базу и накуралесить прямыми вставками в таблицу, а предьявлять юзеры будут не мне, а тебе. И ламер воинствующий будет в первых рядах. И прав он будет, кстати.
:)


 
Sergey13 ©   (2005-07-01 15:45) [18]

2[15] Stakan ©   (01.07.05 15:38)
А я тоже самое могу и без ХП сделать? И что?

2 [16] Danilka ©   (01.07.05 15:43)
Нет вроде.

2[17] Danilka ©   (01.07.05 15:43)
Воинствующие ламеры победят и накуролесят по любому. 8-)


 
Stakan ©   (2005-07-01 15:48) [19]

Danilka ©   (01.07.05 15:43) [17]
Я уже говорил, что случаи бывают разные :)

> Хотя-бы тем, что я (или любой другой воинствующий
> ламер :) ) могу зайти в твою базу и накуралесить
> прямыми вставками в таблицу, а предьявлять юзеры будут
> не мне, а тебе. И ламер воинствующий будет в первых
>рядах. И прав он будет, кстати.
> :)

А на этот случай есть разграничения прав доступа.


 
Danilka ©   (2005-07-01 15:59) [20]

Sergey13 ©   (01.07.05 15:45)

Понятно. Очень жаль. :)

Stakan ©   (01.07.05 15:48)

Есть еще одна проблема - когда у тебя несколько сот таблиц и еще больше ХП разобраться новому человеку (да может и тебе самому, через какое-то время) будет довольно сложно. А с триггером - проще.

Далее, для "Как правило, в сложных системах после добавления записи требуется выполнить ещё ряд действий с этой записью (например,  зарегистрировать добавление)" можно использовать тот-же самый триггер.

Если-же требуется именно на клиенте узнавать ИД вставленной записи, то это тоже решаемо.:)
Я-бы тогда использовал триггер, но немного не такой: в триггере проверял-бы - если вставляемое значение ИД - NULL, то генерим новое, если что-то другое, то вставляем его. А уж где дернут генератор - на клиенте отдельным запросом, или еще и ХП оставить - дело десятое. :)
Кажись, именно так в ИБ обычно и делаецца, эх давненько с ним не работал.


 
Danilka ©   (2005-07-01 15:59) [21]

Stakan ©   (01.07.05 15:31)

> На твое имхо есть мое, которое категорически
> несогласное

Обоснуй чем плоха ХП


Хотя-бы тем, что я (или любой другой воинствующий ламер :) ) могу зайти в твою базу и накуралесить прямыми вставками в таблицу, а предьявлять юзеры будут не мне, а тебе. И ламер воинствующий будет в первых рядах. И прав он будет, кстати.
:)


 
Danilka ©   (2005-07-01 16:03) [22]

сорри за [21] обкатываю клиента форума от Ломброзо. :)


 
Stakan ©   (2005-07-01 16:16) [23]

Danilka ©   (01.07.05 15:59) [20]

> Есть еще одна проблема - когда у тебя несколько сот
> таблиц и еще больше ХП разобраться новому человеку (да
> может и тебе самому, через какое-то время) будет
> довольно сложно. А с триггером - проще

Если система большая, то пользуются спец. средствами.


> Далее, для "Как правило, в сложных системах после
> добавления записи требуется выполнить ещё ряд действий
> с этой записью (например,  зарегистрировать
> добавление)" можно использовать тот-же самый триггер.

Согласен, не не всегда.

> Если-же требуется именно на клиенте узнавать ИД
>вставленной записи, то это тоже решаемо.:)
> Я-бы тогда использовал триггер, но немного не такой: в
> триггере проверял-бы - если вставляемое значение ИД -
> NULL, то генерим новое, если что-то другое, то
> вставляем его. А уж где дернут генератор - на клиенте
> отдельным запросом, или еще и ХП оставить - дело
> десятое. :)

ИМХО неудачный подход, вставка первичных ключей должна делаться централизовано, единообразно.

> Кажись, именно так в ИБ обычно и делаецца, эх
> давненько с ним не работал.

Я тоже последнее время всё больше по Ораклу ;)


 
evvcom ©   (2005-07-01 16:24) [24]


> Я тоже последнее время всё больше по Ораклу

И в Оракле тоже ключи в ХП генеришь? :)


 
Val ©   (2005-07-01 16:25) [25]

почему бы и нет, если там же insert происходит :)


 
Danilka ©   (2005-07-01 16:30) [26]

Stakan ©   (01.07.05 16:16)
ИМХО неудачный подход, вставка первичных ключей должна делаться централизовано, единообразно.


На мой взгляд, вполне достаточно централизованного генератора. :) И для ИБ вариант, когда есть и триггер и ХП вполне жизнеспособен. "Я так думаю." :)

Val ©   (01.07.05 16:25)
почему бы и нет, если там же insert происходит :)


А в Орокле нет проблем с вытаскиванием ИД после инсерта в таблицу, так шта, плюсов у вариантов с ХП там нет. :)


 
Stakan ©   (2005-07-01 16:31) [27]

evvcom ©   (01.07.05 16:24) [24]
Именно :) Ещё раз оговорюсь, речь идёт именно о больших системах (несколко тысяч таблиц в БД).
Все действия с таблицами осуществляются через сложные ХП, на которые у юзеров есть права на выполнение, а самих таблдиц они даже не видят (для отображения используются представления).
Если программка небольшая (десяток таблиц, никаких сложных обработок), то подойдут и триггеры.


 
Danilka ©   (2005-07-01 16:37) [28]

Stakan ©   (01.07.05 16:31)
evvcom ©   (01.07.05 16:24) [24]
Именно :) Ещё раз оговорюсь, речь идёт именно о больших системах (несколко тысяч таблиц в БД).
Все действия с таблицами осуществляются через сложные ХП, на которые у юзеров есть права на выполнение, а самих таблдиц они даже не видят (для отображения используются представления).
Если программка небольшая (десяток таблиц, никаких сложных обработок), то подойдут и триггеры.


Они и в твоем варианте подойдут. :)
Тем более, что работаешь с вьюхами - чем плох вариант с instead of триггерами?
Впрочем, что-то мне это напоминает..
:)

Но для орокла, на мой скромный взгляд, все-таки вариант с тригером на таблице предпочтительнее, а в ХП или триггере на вьюхе делать инсерт в таблицу с ретурнингом.


 
Val ©   (2005-07-01 16:38) [29]

>[26] Danilka ©   (01.07.05 16:30)
Я имел ввиду что без разницы, если вы делаете инсерт в самой хп:
1) достанете ли вы .NextVal в процедуре прямо перед вставкой и во вставке будете использовать лок. переменную;
2) либо возвратите его после вставки в эту же переменную с помощью returning.
Но это оффтоп. Сорри.


 
Stakan ©   (2005-07-01 16:42) [30]

Danilka ©   (01.07.05 16:37) [28]
Короче оба варианта имеют право на жизнь ;)

> Впрочем, что-то мне это напоминает..

Что?


 
Danilka ©   (2005-07-01 16:48) [31]

Val ©   (01.07.05 16:38)
>[26] Danilka ©   (01.07.05 16:30)
Я имел ввиду что без разницы, если вы делаете инсерт в самой хп:
1) достанете ли вы .NextVal в процедуре прямо перед вставкой и во вставке будете использовать лок. переменную;
2) либо возвратите его после вставки в эту же переменную с помощью returning.
Но это оффтоп. Сорри.


Когда есть три десятка разработчиков, хоть и маловероятна, но все-же имеет место быть такая ситуация, когда какой-нибудь молодой, которому из своей задачи есть надобность заполнять какой-то справочник, и он, не увидев триггера на таблице этого справочника втупую будет инсертить с ид равном select max(id)+1 ...
Сейчас, правда, у нас в конторе собираются "поделить" все объекты БД на разработчиков, где у каждого объекта будет известен ответственный, правда для решения других проблем, но и эта станет еще менее вероятная, но все-же..


 
Danilka ©   (2005-07-01 16:48) [32]

Stakan ©   (01.07.05 16:42)
Danilka ©   (01.07.05 16:37) [28]
Короче оба варианта имеют право на жизнь ;)

> Впрочем, что-то мне это напоминает..

Что?


Спор здесь на форуме, правда не с тобой, на тему вьюхи vs ХП.
:)


 
evvcom ©   (2005-07-01 17:13) [33]

Да, да... Был такой спор.
Я тоже за триггера. Тот же молодой разработчик может сделать вставку и не через ХП, а триггер случайно не обойдешь. Да и сам я при тестировании зачастую вставляю данные напрямую в таблицу. Мне так удобнее.


 
Val ©   (2005-07-01 17:17) [34]

Вцепились вы в "молодого разработчика". Существует понятие корпоративных стандартов. По ним и работают - не знает, так нарушит не только вставку. Не аргумент это все-таки, по-моему.


 
evvcom ©   (2005-07-01 17:23) [35]

Хорошо. Тогда про централизованную генерацию ключей. Триггер, куда более централизованней. А с ХП. Писать отдельно, зачем? Если в общей куче с другими действиями, тогда такой вариант, если вдруг надо вставить в таблицу данные из нескольких мест, везде спец. ХП вызывать? Куда лучше триггер. Все имхо.


 
Val ©   (2005-07-01 17:27) [36]

Да оба варианта нормальны и применимы. В той же процедуре можно будет избежать мутации, например, если при вставке нужно анализировать текущую таблицу.


 
reticon ©   (2005-07-01 17:32) [37]

да ладно вам хваит спорить, здесь все написано
http://www.ibase.ru/devinfo/generator.htm :)

Кстати на данную статью наткнулся еще давно, прочитал, вроде разобрался сразу, а счас "доразбираться" пришлось :)

ЗЫ кстати, тригеры ил ХП в моем случае разницы нет, сейчас реализовано на ХП. Эррор выскакивал есессно по глупости - была для отладки вставлена строчка перед добавлением записи в параметр запроса переменную IParam := MainForm.DataSource1.DataSet.FieldByName("ID").Value на что и была ругань при пустом датасете :)



Страницы: 1 вся ветка

Текущий архив: 2005.08.07;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.052 c
3-1120301637
Cardinall
2005-07-02 14:53
2005.08.07
Как узнать работают ли пользователи с сервером


1-1121954764
serg128
2005-07-21 18:06
2005.08.07
Как закрыть программу?


1-1121449372
lookin
2005-07-15 21:42
2005.08.07
Печать из TStringGrid


14-1121449154
Shuric
2005-07-15 21:39
2005.08.07
Подмена понятий :)


4-1117900157
NeoVariant
2005-06-04 19:49
2005.08.07
Свой текст в подсказке для TrayIcon состояние соединения