Конференция "Базы" » Обновление таблицы через RDS-ADO [D7, MSSQL]
 
  • elonir (11.06.12 19:12) [0]
    Доброго времени суток, господа.

    И снова тот самый пример из папки DEmos, посвященный RDS-ADO

    Добавил на сервер свойство для чтения и записи, соответственно появился метод для записи.

    Как правильно осуществлять запись в БД с клиента?

    Если поставить навигатор и просто добавлять, к примеру, запись в дбгрид, то на рефреш возникает ошибка "недостаточно сведений из основной таблицы для обновления". Первичный ключ здесь очевидно не причем, потому что на удаление такая же проблема.

    Код на клиенте банален:
    RDSConnection1.Close;
    ADODataSet1.Close;
    ADODataSet1.Open;

    Код метода обновления на сервере (Метод появляется при добавлении в библиотеку типов свойства на запись/чтение)
    try
       AdoConnection1.BeginTrans;
       Value.UpdateBatch (adAffectAll);
       AdoConnection1.CommitTrans;
     except
       on E:Exception do
       begin
        AdoConnection1.RollbackTrans;
         ShowMessage(E.Message);
       end;
    end;

    Я конечно в курсе, что многие посоветуют написать на бумажке слово RDS после чего бумажку сжечь и воспользоваться сокетами или чем еще, но отвертеться от РДС никак не могу.

    Беда всей темы в том, что найти нормальный гайд трудно, а книжку Елмановой уже не так просто найти)

    Спасибо
  • sniknik © (11.06.12 20:46) [1]
    > "недостаточно сведений из основной таблицы для обновления".
    > Первичный ключ здесь очевидно не причем, потому что на удаление такая же проблема.
    ??? ошибка явная, и понятная. выводы не понятны. для удаления типа идентификация записи не нужна?
  • elonir (11.06.12 21:03) [2]
    Дело в том, что таблица загружается целиком в дбгрид, и в том числе, с полем ID, и при удалении информация об ID имеется.

    При добавлении записи поле ID не поддается редактированию в дбгриде оО, может это и логично ибо ID назначается инкрементом.

    Очевидно, что я что-то делаю неправильно, как мне лучше организовать обновление?
    Потому что если просто подключить датасет напрямую через строку подключения на локальной машине, то привязанный к нему дбгрид превосходно все обновляет и никаких ID не просит
  • elonir (11.06.12 21:14) [3]
    Согласно примеру, организовал все так:

    на сервере есть свойство Property1 с доступностью Read\WRITE и методами

    function TLOL.Get_Property1: _Recordset;
    begin
     Result := CoRecordSet.Create;
     Result.CursorLocation := adUseClient;
     Result.Supports(adUpdateBatch);
     Result.Open('units', ADOConnection1.ConnectionString, adOpenDynamic, adLockBatchOptimistic, adCmdUnspecified);
    end;

    procedure TLOL.Set_Property1(const Value: _Recordset);
    begin
    try
       AdoConnection1.BeginTrans;
       Value.UpdateBatch (adAffectAll);
       AdoConnection1.CommitTrans;
     except
       on E:Exception do
       begin
        AdoConnection1.RollbackTrans;
         ShowMessage(E.Message);
       end;
    end;
    end;

    На клиенте тупо открывается датасет, привязанный по RDSConnection, в свойстве CommandText которого указано "Property1"

    RDSConnection1.Close;
    ADODataSet1.Close;
    ADODataSet1.Open;

    Данные успешно загружаются, но обновлению не подлежат(

    Вот собственно в том и вопрос, как сделать их обновляемыми, смущает adUpdateBatch, просто не знаю пока как организовать правильно
  • sniknik © (11.06.12 21:18) [4]
    > и при удалении информация об ID имеется.
    этого мало, надо указать что обновление идет по ключу. (почитай статьи на королевстве дельфи про ADO)

    + открываешь почему то ADODataSet1.Open; а запить в Value.UpdateBatch (adAffectAll); ???
    плюс откуда то взялся коннект  AdoConnection1.BeginTrans;, откуда если RDSConnection1. уж не на сервере ли рулить пытаешься?... а он откуда данные возьмет без передачи с клиента?
  • elonir (11.06.12 21:36) [5]
    >этого мало, надо указать что обновление идет по ключу.
    >> если просто подключить датасет напрямую через строку подключения на локальной машине, то привязанный к нему дбгрид превосходно все обновляет.

    Первичный ключ в таблице есть

    >+ открываешь почему то ADODataSet1.Open; а запить в Value.UpdateBatch (adAffectAll);

    Да, именно это смущает, я просто нашел такой пример, он не совсем подходит, поскольку для другого случая, я просто банально не знаю как это сделать правильно.

    >>плюс откуда то взялся коннект AdoConnection1
    Ну тут так: Есть клиент и сервер приложений. Сервер приложений подсоединяется через АДО к базе (через строку подключения), а клиент к серверу - через RDS.

    В данном случае RDS предоставляет клиенту доступ к свойствам Com-объекта - сервера приложений. Свойство Property1 имеет два метода - на чтение и запись. При обращении к имени свойства на клиенте фактически вызывается метод чтения.

    Вот я никак не могу понять, когда вызывается метод на запись, и что должно быть в его реализации на сервере. Пока исходил из того, что при обновлении рекордсета датасета должен вызываться метод записи, вероятно это не так(

    Был бы очень благодарен, если бы кто-нибудь привел пример, как должен выглядеть этот метод, и каким образом обратиться к нему в клиенте, в этом, собственно мой вопрос и заключался)
  • sniknik © (11.06.12 22:26) [6]
    > я просто нашел такой пример
    а подумать?
    > Сервер приложений подсоединяется через АДО к базе (через строку подключения), а клиент к серверу - через RDS.
    ВОТ ТУТ, все правильно написано, так и должно быть. а в коде почему то бред.

    > Был бы очень благодарен, если бы кто-нибудь привел пример
    кто его писать будет? нафига оно нам? мне по крайней мере. когда то изучал/искал/писал примеры... после неудач с внедрением бросил это дело.

    единственное, что помню/или по логике должно быть, могу посоветовать...
    так например 2, или даже 3 важных момента
    1 UpdateBatch делается с клиента, там где вносятся/меняются данные (там же должна быть настройка adUpdateBatch).
    2 на сервере достаточно одного ADOConnection1...
    3 блин, выкинь из кода все несущественное для тебя пока ну типа, BeginTrans, CoRecordSet.Create; псевдо обработку ошибок ShowMessage(E.Message); (вот что, серьезно стандартного сообщения мало/оно кривое чтобы в тесте вот эту хрень вставлять?)  вместо одной строки кода, важной, у тебя получается 50... а ты еще хочешь разобраться...

    и да, начни со стандартного демо, которое сам же приводил. просто добавь кнопку с UpdateBatch(без параметров пока), как можно проще в общем... работает? добавь еще, и т.д.
  • elonir (11.06.12 23:03) [7]
    Спасибо за терпение)

    > на сервере достаточно одного ADOConnection1...
    так оно одно и есть)

    >блин, выкинь
    само собой, это так, осталось просто с первых попыток

    > и да, начни со стандартного демо
    в стандартном демо есть только чтение, в том и беда)

    >CoRecordSet.Create
    Ну без этого никак. Это собственно и было в демо.

    Пример с батчем взял отсюда:
    http://www.delphigroups.info/2/da/224270.html

    это единственный пример который я нашел. я понимаю что он для другого случая, но данные должен обновлять, попробовать должен был, надеялся что ткнут и скажут - "ненене так нельзя, тут все просто, надо так и так".

    Разумеется не рассчитывал, что для меня кто-то будет что-то рюхать заново, просто понадеялся что кто-то уже поборол эту проблему и сможет подсказать.

    В любом случае спасибо, продолжу долбаться, авось повезет. Если решу проблему, напишу как, мало ли кого заставят делать трехзвенку на рдс
  • elonir (12.06.12 00:35) [8]
    Пример в ссылке работает, между прочим. Если повесить обновление на отдельную кнопку и обращаться к обновляющему методу на сервере в в ее обработчике - то все хорошо.

    Однако ошибка при рефреше навигатора "недостаточно сведений из основной таблицы для обновления" все равно возникает, в то время когда к той же таблице тот же ДатаСет спокойно подключается через строку, и обновляется без проблем. Вопрос изменения "на лету" через свойство сервера остается открытым.
  • sniknik © (12.06.12 10:54) [9]
    > Пример в ссылке работает, между прочим. Если повесить обновление на отдельную кнопку и обращаться к обновляющему методу на сервере в в ее обработчике - то все хорошо.
    а может он под это и написан? с чего взял что при UpdateBatch должен вызываться (ADO вызывает) именно этот метод? точку останова в нем поставь останавливается?

    > "недостаточно сведений из основной таблицы для обновления"
    читай выше я уже ответил от чего такое.

    и кстати, пример в Demo тоже работает между прочим... проверил. одна кнопка с UpdateBatch() в клиент добавляется... и все обновляется, выбирать только RDSServer.DataFactory. если же выбирать самописный сервер, то там нужно исправить adUseClient на adUseServer в Get_Employee и все тоже начинает обновляться. ну или ищи как метод апдейта реально описывается и пиши его самостоятельно. пример из ссылки явно делает неправильно раз не работает в обычном режиме.
  • sniknik © (12.06.12 10:58) [10]
    ++
    в примере "из ссылки" еще есть глюк похоже (если это реально должен быть метод на стандартный апдейт), т.к. этот апдейт посылает только изменения, т.е. малую часть рекордсета в основном, а в примере эти изменения принимаются как целая таблица.
  • elonir (12.06.12 13:28) [11]
    >>должен вызываться (ADO вызывает) именно этот метод
    Та в том то и дело, что метод обновления Property1 вообще никогда не вызывается, более того, к нему обратиться через RDS.AppServer нельзя даже.

    Там в примере - это самостоятельный метод, не привязанный к свойству. Сделал аналогично у себя, и работает, вполне устраивает, конфликты и уровни изоляции можно отрабатывать. На том и остановлюсь, сроки уж поджимают)

    Но при этом все равно непонятно, как работать со свойством на запись.  В том и беда, что при подключении через АДОконнект все прекрасно обновляется из дб грида прямиком в базу, в вот если через RDS и свойство, то думать и искать( Это надо уже на COM форум)))

    >>RDSServer.DataFactory
    Ну это понятно, это только на локальной машине. А если в самописном сервере исправить на UseServer, то вылетает "Библиотека не зарегистрирована", пробовал. Наверное это можно как-то поправить, впрочем

    Вообще, спасибо колоссальное за помощь, Sniknik.
    Если после выполнения работы удастся найти более изящный и правильный вариант, обязательно напишу сюда, вдруг кто будет париться.
  • sniknik © (12.06.12 13:39) [12]
    > "Библиотека не зарегистрирована"
    ну так, зарегистрируй. запусти один раз сервер на клиенте.

    > найти более изящный и правильный вариант
    на сокетах, тебе предлагали. все проблемы решаются запуском 1 борландовской службы на сервере.
  • sniknik © (12.06.12 13:43) [13]
    >>>RDSServer.DataFactory
    > Ну это понятно, это только на локальной машине.
    ну естественно... если имя компа не указывать. а вообще это полноценный DCOM сервер. правда у него насколько помню есть ограничение, нужно заранее в настройках сервера, разрешения, все используемые с клиента запросы прописать... или что то типа.
  • KSergey © (13.06.12 17:31) [14]
    Попробуйте почитать тут (все 3 части)
    http://www.delphikingdom.com/asp/viewitem.asp?catalogid=408

    Нельзя сказать, что волшебство и счастье непременно постигнут - но возможно добавят вариантов для поиска счастья.
 
Конференция "Базы" » Обновление таблицы через RDS-ADO [D7, MSSQL]
Есть новые Нет новых   [119674   +112][b:0][p:0.001]