duminică, 28 februarie 2016

delphi как добавить запись через sql запрос через clientdataset

SQL запросы в XML через ClientDataSet

Пока писал на ado для access даже не использовал DataControls, а вот по сабжу появились проблемы, если я не собираюсь использовать TDBGrid или использовать толкьо для чтения, как же мне тогда добавлять, редактировать и удалять записи одним только ClientDataSet"ом? Я пытался прописать самый простой запрос в commandTex но даже он не работает.

sql запросы выполняет sql сервер/движок. сам по себе ClientDataSet не может их выполнять, только если есть провайдер данных/связь с вышеупомянутым (куда он запрос передаст, получив в ответ данные, или ошибку).

для XML насколько знаю никто еще sql сервера не написал.

Хреново! Чтож я тогда взялся на нём писать. Ну ладно, в любом случае там должна быть возможность добавления и изменения записей вручную, не подскажешь как это делается?

Извиняюсь за предыдущий вопрос, просто в последний раз когда я работал с mdb я добавлял и редактировал sql запросами, но чуть раньше я научился добавлять и редактировать компонентой tadotable, а у tclientdataset"а методы всё теже, так что вопрос по редактированию отпадает.

В данный момент проблема несколько другого плана, как сохранять изображения в таблице xml? Я создал поле image типа ftGraphic, в файле таблицы это поле описано следующим образом:

<FIELD attrname="image" fieldtype="bin.hex" SUBTYPE="Graphics"/>

При попытке записать изображение следующим образом:

cds.FieldValues["image"]:=img.Picture.Bitmap;

получаю ошибку о несовместимости типов tbitmap и variant. В общем даже если и найду как сохранить рисунок, то не найду как его от туда достать. Уверен многие знают как это делается и как это делается правильно. Прошу поделиться опытом.

Секреты Delphi. Использование TClientDataset в двухуровневых приложениях. Часть 3

Секреты Delphi. Использование TClientDataset в двухуровневых приложениях. Часть 3

Наконец настало время первых опытов. К сожалению, не удалось найти оригинальный код демонстрационных компонент Дана Мишера, так что придется воспользоваться созданной несколько лет назад на их базе компонентой TBS_ClientDataset.

Найти ее можно по адресу http://berdachuk.at.tut.by/downloads/bs.zip (эта библиотека компонент бесплатна и содержит исходные коды). Для данного примера также воспользуемся еще одной компонентой TBS_ADODataset названной библиотеки. TBS_ClientDataset для Delphi 5 является наследником стандартной компоненты TClientDataset.

Создадим простой проект в Delphi, содержащий одну форму frmMain и два модуля данных dmClient и dmRemote. Развивая тему использования сервера БД Oracle 9i Lite, воспользуемся демонстрационной базой данных POLITE. При отсутствии Oracle 9i Lite можно воспользоваться демонстрационной базой данных \Borland Shared\Data\DBDEMOS.mdb, входящей в пакет поставки Delphi.

Наиболее простым способом соединения с базой данных в этом случае будет использование компонент ADO. Для соединения с сервером в модуль dmRemote добавим компоненту TADOConnection. При стандартной установке сервера Oracle 9i Lite алиас ODBC-соединения POLITE должен быть прописан автоматически. Если для установки использовался клиентский CD, то придется создать его самостоятельно. Для настройки соединения нажмем кнопку "…" свойства ConnectionString и выберем режим использования строки соединения см. рис. 1.

Информацию по дальнейшей настройке можно найти в статье "Секреты Delphi. Соединение с базами данных при помощи компонент ADO" (КГ №2/2004). Добавим в этот же модуль компоненту TBS_ADODataset палитры компонент BS (назовем ее rdsDept). Свяжем свойство Connection с компонентой TADO_Connection. Для настройки SQL Текста нажмем кнопку "…" свойства CommandText и в появившемся SQL-редакторе введем запрос к таблице отделов см. рис. 2.

Основное отличие компоненты TBS_ADO Dataset от TADODataset, наследником которой она является, — наличие дополнительного свойства UniqueFields. В данное свойство через точку с запятой можно прописать список полей, которые будут уникально идентифицировать текущую запись. Это требуется для обеспечения возможности редактирования традиционно ReadOnly наборов данных, а также в случаях, если первичные ключи для выбранного сервера БД определяются некорректно. Если данное свойство не заполнять, то будет вызываться стандартная функция PSGetKeyFields интерфейса IProviderSupport компоненты TADODataset.

Добавляем в модуль dmRemote компоненту TDatasetProvider палитры компонент midas и связываем ее свойство Dataset с добавленной ранее компонентой rdsDept. Получим следующую картину (см. рис. 3).

Свойство ResolveToDataset устанавливаем в значение false, что позволит передать управление процессом подтверждения изменений встроенной компоненте TSQLResolver, которая передает изменения сразу компоненте, которая связана с сервером базы данных — в нашем случае это dbConnection. Это позволяет исключить необходимость использования дополнительных компонент (например, TUpdateSQL), скрипты InsertSQL, DeleteSQL и UpdateSQL будут формироваться автоматически.

Свойство UpdateMode устанавливаем в значение upWhereKeyOnly. При наличии первичных ключей это существенно повысит скорость поиска записи сервером базы данных во время внесения изменений.

Применительно к серверу Oracle, если требуется указание схемы, что желательно для разграничения доступа, надо будет реализовать метод, возвращающий имя редактируемой таблицы события OnGetTableName. Внутренняя реализация данного метода при указании имени схемы перед именем таблицы возвращает неверный результат. Этот же метод потребуется для обеспечения возможности редактирования ReadOnly наборов данных.

procedure TdmRemote.dspDeptGetTableName(Sender: TObject; DataSet: TDataSet;

var TableName: String);

TableName:='System.Dept';

Теперь настало время клиентского модуля данных. Добавим в него компоненту TBS_ ClientDataSet. В родительском компоненте TClientDataset используется свойство Provider Name для связи с провайдером TDatasetProvider. Но при размещении компонент связки TClientDataset и TdatasetProvider в различных модулях программы список провайдеров становится недоступен. Для решения данной проблемы в TBS_ClientDataset добавлено свойство DataProvider. Устанавливаем данное свойство в dmRemote.dspDept. Реализация метода SetData Provider позаимствована из статьи Дана Мишера "Using the MIDAS ClientDataSet as a Replacement for Cached Updates".

Теперь появляется возможность открывать полученный набор данных. Добавим в этот же модуль компоненту TDataSource, позволяющую связывать наш TClientDataset с элементами управления. Для защиты от случайных изменений данных пользователями желательно установить значение свойства AutoEdit в false. В результате этих манипуляций клиентский модуль данных будет иметь вид, как на рис. 4.

Начиная с данного момента данные уже можно редактировать, но на сервер результаты сделанных изменений посылаться не будут. Реализация метода отсылки данных на сервер определяется принятой схемой работы. В простейшем случае можно производить эту операцию сразу после фиксации данных методом post, а также удаления данных. В нашем примере реализуем следующие методы:

procedure TdmClient.cdsDeptApplyUpdates;

if cdsDept.ChangeCount > 0 then

cdsDept.ApplyUpdates(-1);

procedure TdmClient.cdsDeptAfterDelete(DataSet: TDataSet);

cdsDeptApplyUpdates();

procedure TdmClient.cdsDeptBeforeClose(DataSet: TDataSet);

if (cdsDept.State in [dsInsert,dsEdit]) then

cdsDept.Post;

В главной форме для примера разместим кнопку открытия, DBGrid и DBNavigator. Пример работы программы показан на рис. 5.

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

procedure TdmClient.DataModuleDestroy(Sender: TObject);

if (self.Components[i] is TBS_ClientDataSet) and

(TBS_ClientDataSet(self.Components[i]).Active) then

Фактически в компоненте TClientDataSet можно редактировать только текущую запись и извлекать значение только из текущей записи. Текущая запись это та запись, которая имеет фокус ввода в данный момент. Для того чтобы некоторая запись стала текущей её должен выделить пользователь, также её можно выделить программно. Для того используется метод Locate.

Locate (const KeyFields: string; const KeyValues: Variant; Options:

TLocateOptions): Boolean;

Первый параметр это список полей разделяемых "точкой с запятой" либо одно поле. Второй параметр это значения, которым должны быть равны поля указанные в первом параметре если полей много то во втором параметре должен быть массив из Variant. Если указано несколько полей то переход осуществляется, только если каждое поле, указанное в первом параметре равно значению, указанному во втором параметре. Если переход прошёл успешно, то функция возвращает True. Для того чтобы получить массив из Variant можно использовать функцию VarArrayOf. Вот примеры использования метода Locate:

If not ClientDataSet1.Locate('LastName',Edit1.text,[]) then

MessageDlg(' " '+Edit1.text+' " не найдено', mtError, [mbOK], 0);

ClientDataSet1.Locate('LastName;FirstName', VarArrayOf( ['Иванов', 'Иван'] ), []);

Если нужно перейти к записи, зная лишь часть строкового поля можно использовать опцию loPartialKey в третьем параметре.

ClientDataSet1.Locate('Address','Mosk',[loPartialKey]); Часть значения не может быть где-то посередине поля она может составлять лишь несколько символов сначала.

Delphi.Datasnap. Провайдеры. Как добавить новую запись (insert)?

В данном посте будем учиться вставлять записи Insert. Для этого нужно провести подготовительную работу на сервере, обновить класс методов сервера у клиента, и вызывать соответствующие методы со стороны клиента. Всего существует 3 способа –

Через TServerMethods. На мой взгляд менее удобный в смысле трудоемкости (особенно для select). Нет зависимости от COM. (Рассмотрим в других постах, так как надо будет менять набор компонентов)

Через провайдеры и прямую отправку SQL запросов. На мой взгляд более удобный – менее трудоемкий. Есть зависимость от COM. (Рассмотрим здесь)

Через провайдеры и методы ClientDataSet   – (Insert, Edit, Delete) Самый легкий способ.(Рассмотрим здесь)

В данном посте рассмотрю только  способы – через провайдеры  как более простой и удобный на мой взгляд. Новый способ рассмотрю в других постах.

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

INSERT через провайдеры и прямую отправку SQL запросов

Какие компоненты используем на сервере?

В методах сервера выставляем такие компоненты…

Niciun comentariu:

Trimiteți un comentariu