Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Работа с unidac и ehlib


Автор: KAMIKAZE 7.2.2011, 17:40
Установил сегодня компоненты  unidac и ehlib. Подключился к базе и вывел ее содержимое, все кажется довольно просто.  

Появились вопросы: 
1. увидел очень полезную вещь в DBGridEh - можно включить TRowDetailPanelEh, что дает "+" для каждой записи. Это то что мне нужно, я хочу отображать дополнительную информацию на нажатии на "+" из другой базы по общему ключу. Для примера я прикрепил архив, в нем в папке "Mysql Db query" есть два SQL файла для создания таблиц в MySQL.  Таблица test1 содержит поля: id и name, а таблица test2 поля: idimageurl .... и т.д.
Как сделать, что бы по нажатию на "+" в открытом TRowDetailPanelEh отображалась информация(тоже в DBGridEh ) из таблицы test2
Квери которая выберет колонку должна быть(немного абстрактно smile) : select * from test2 where id="DBGridEh.selected.id"

2.  как обрабатывать исключения о любых ошибках связанных с запросами.
3. у меня есть поле imageurl, она указывает на картинку в интернете, как лучше загрузить эту картинку и отобразить в базе? или проще в Image, рядом с панелью? делать это когда пользователь кликает на любом Row.

4. как лучше и быстрее всего записывать информацию в базутаблицу используя эти компоненты? Например прикрепленные SQL файлы содержат квери для создания таблицы и наполнения. Просто в UniQuery загружаю ее и все? А как получать лог выполненного действия? Ошибки записи и\или выборки.

5. как получить в TreeView все базы и таблицы? 

Хотелось бы еще услышать наставления smile  Может я немого не тем путем иду? Какие то подводные камни есть? Как Вы считате? Хочется увидеть толковые примеры.



Автор: superVad 7.2.2011, 20:56
Задавай лучше вопросы по одному. А то их тут много и почти все заданы не корректно. Как то колупаться в этом потоке сознания не хочется.

Автор: KAMIKAZE 7.2.2011, 22:55
Я не знаю как перефразировать smile  Вроде бы по одному разделил вопросы. Один вопрос по TRowDetailPanelEh, другой по исключениям, третий по загрузке изображения ну и т.д.  По вложениям видно что у меня получилось и о чем задаю вопросы.

Автор: superVad 7.2.2011, 23:09
KAMIKAZE, ну для начала ты очень вольно используешь слово "база". В первом вопросе, скорее всего, имеется ввиду таблица, в третьем - грид, в последнем вообще не понятно, что ты кроме таблиц еще собираешься отображать в дереве.
Под разделить я имел ввиду - по теме на каждый вопрос. Чего то мне кажется, что всем так будет удобнее.

Тут такая http://forum.vingrad.ru/forum/topic-40345.html вверху раздела есть - лишним не будет почитать.

Автор: KAMIKAZE 8.2.2011, 01:31
Кажется все правильно, в 4-м вопросе только исправил слову базу на таблицу, но и так понятно.... 

Вот как нужно сделать ( это вопрос №5) 


http://s2.ipicture.ru/

Автор: Vas 8.2.2011, 16:14
1. select * from test2 where id=:ID
свойство MasterSource:= датасурс первого датасета. Все само будет связываться

2. try
except
end;

3. Загрузить в БД, url может быть недоступным. А как отобразить из базы, посмотри примеры, в папке дельфи/Demos есть аналогичное

4. Для скриптов создания таблиц и запихивания в БД лучше использовать соответствующий компонент UniScript, посмотри есть такой или нет, у меня в ODAC есть (производитель тот же, только компоненты не универсальные)

5. Ну это целая история. Читаешь БД, запихиваешь в TreeView и ChildNode им пустые создаешь, чтобы можно было ветвь открыть, затем при открытии (Expanding) читаешь соответствующие ресурсы и аналогично добавляешь, только уже к ветке выделенной, соответственно пустую ветвь сразу надо удалить. С уровнями придется определиться заранее.

Добавлено через 2 минуты и 39 секунд
Да, кстати, один вопрос - одна тема. Так ща запутаемся на что отвечали, на что нет.

Автор: KAMIKAZE 14.2.2011, 22:37
1. Немного не понял. Получилось сделать  select * from test2 where id=:ID, только немного глючит, не сразу понимает. Я обрабатываю метод "DBGridEh1CellClick" 
В нем ставлю переменную ID=Column.Field.AsString; Далее  DBGridEh1RowDetailPanelShow  формирует квери используя переменную ID. Но метод DBGridEh1CellClick не обрабатывается сразу на клике по +. Как его обработать то, клик на "+"?   (что получилось прикрепил)
А вот "MasterSource:= датасурс первого датасета"   это как сделать не понятно.

2. Решен  smile 
3. Решен.
4. Решен.
5. Как считать БД? Получить список баз и таблиц в них?


з.ы. у меня столько мелких вопросов, что на каждый тему создавать... smile 


Автор: Vas 15.2.2011, 08:40
Цитата(KAMIKAZE @  14.2.2011,  22:37 Найти цитируемый пост)
1. Немного не понял. Получилось сделать  select * from test2 where id=:ID, только немного глючит, не сразу понимает. Я обрабатываю метод "DBGridEh1CellClick" 
В нем ставлю переменную ID=Column.Field.AsString; Далее  DBGridEh1RowDetailPanelShow  формирует квери используя переменную ID. Но метод DBGridEh1CellClick не обрабатывается сразу на клике по +. Как его обработать то, клик на "+"?   (что получилось прикрепил)
А вот "MasterSource:= датасурс первого датасета"   это как сделать не понятно.

Чего не понятного то? ДБГрид у тебя связан с DataSource1, а тот в свою очередь с UniQuery1. С запросом типа
Код

select id, name from table1

На RowPanel датагрида вешаем еще один грид и кидаем на форму DataSource2 и UniQuery2, связываем их с ДБГридом вторым, пишем запрос типа
Код

select * from table2 where id_из_табла1=:ID

И свойству UniQuery2.MasterSource:=DataSource1;
Ну и открываем их оба, больше ничего обрабатывать не надо, при изменении положения курсора в 1 таблице, вторая будет автоматом показывать подчиненные ей записи

Цитата(KAMIKAZE @  14.2.2011,  22:37 Найти цитируемый пост)
5. Как считать БД? Получить список баз и таблиц в них?

Ну, а это смотря какая БД. Читай доки на нее и выполняй запросы.

Автор: KAMIKAZE 15.2.2011, 23:17
Цитата(Vas @  15.2.2011,  08:40 Найти цитируемый пост)
Чего не понятного то? ДБГрид у тебя связан с DataSource1, а тот в свою очередь с UniQuery1. С запросом типа

Да.


Цитата(Vas @  15.2.2011,  08:40 Найти цитируемый пост)
На RowPanel датагрида вешаем еще один грид и кидаем на форму DataSource2 и UniQuery2, связываем их с ДБГридом вторым, пишем запрос типа

Так и сделано. А куда писать запрос? На каком событии? 

Цитата(Vas @  15.2.2011,  08:40 Найти цитируемый пост)
И свойству UniQuery2.MasterSource:=DataSource1;

ТОже непонятно на каком событии, и потом назад ставить нужно?

Автор: KAMIKAZE 15.2.2011, 23:33
А нету готового примера для построения дерева баз и таблиц?

Автор: Vas 16.2.2011, 08:59
Цитата(KAMIKAZE @  15.2.2011,  23:17 Найти цитируемый пост)
Так и сделано. А куда писать запрос? На каком событии? 

Ни на каком событии, запрос пишешь в свойстве SQL компонента UniQuery1 и UniQuery2.

Цитата(KAMIKAZE @  15.2.2011,  23:17 Найти цитируемый пост)
ТОже непонятно на каком событии, и потом назад ставить нужно?

Связываем в дизайн-тайм в инспекторе объектов.

Единственное условие - это при показе формы или в дизайнере надо открыть оба набора данных и все должно само связаться. А ну еще в первом запросе должно быть поле с именем параметра второго запроса, смотри мой предыдущий пост, там в первом запросе явно выбрано поле ID, а во втором параметр с таким же именем.

Цитата(KAMIKAZE @  15.2.2011,  23:33 Найти цитируемый пост)
А нету готового примера для построения дерева баз и таблиц? 

Примера нет, ищи в инете, в частности основы http://www.delphikingdom.com/asp/viewitem.asp?catalogid=488
Для мускуля выбор всех БД
Код

show databases

Выбор всех таблиц
Код

show tables

Автор: KAMIKAZE 16.2.2011, 16:01
Цитата(Vas @  16.2.2011,  08:59 Найти цитируемый пост)
Единственное условие - это при показе формы или в дизайнере надо открыть оба набора данных и все должно само связаться. А ну еще в первом запросе должно быть поле с именем параметра второго запроса, смотри мой предыдущий пост, там в первом запросе явно выбрано поле ID, а во втором параметр с таким же именем.


т.е. квери будет такая(я еще не работе, не могу проверить, вечером помучаю  smile ) 

Код

select * from table2 where table1.id????   // не понятно)


Квери ведь должна быть сформирована с проверкой на полей айди, текущей выделенной, мне не понятно какого она рода должна быть.

Может я не правильно спросил насчет дерева таблиц. Мне нужно сделать копию функционала как в SQLYog т.е. при подключении в любому серверу(либо MySQL либо MSSQL), у меня отображаются все базы. Ну это делается запросом  
Код

show databases

 а вот далее как пройтись по этому списку и сделать выборку таблиц? затем полей. И так для MySQL либо MSSQL в зависимости от текущего подключения. Очень странно, что нету готового компонента, например от UniDAC, придется что ли изобретать велосипед.

Автор: Vas 16.2.2011, 16:45
Читай книги, в разделе по работе с БД есть примеры связывания таблиц, аналогично вяжутся и запросы.

Для каждой БД свой синтаксис запросов для получения БД, таблиц, я привел для MySQL. MSSQL я не знаю

Автор: KAMIKAZE 17.2.2011, 00:03
Все равно не понятно какую квери написать. Можешь пожалуйста на примере что я приатачил в постах выше написать как надо. 

И вот можно для MySQL использовать код 
Код

SHOW DATABASES;
SHOW TABLES IN <databasename>
USE <databasename>; EXPLAIN tablename;


А как получать результаты его выполнения? Например даже я делаю запрос выборки всех полей, то как его считать, результат запроса?
Можно с  помощью DBGridEh1 сделать такую деревовидную структуру, ну как в sqlyog? 

Автор: Vas 17.2.2011, 08:09
Цитата(KAMIKAZE @  17.2.2011,  00:03 Найти цитируемый пост)
Можешь пожалуйста на примере что я приатачил в постах выше написать как надо.

Не могу, у меня нет компонентов UniDac.
Прежде чем показать таблицы БД, надо выбрать БД в MySQL, т.е. выполнить запрос
Код

use имя_базы_данных;


Ну когда запрос открыт перемещаешься по строкам выборки и добавляешь данные в TreeView. И добавляешь фиктивную пустую ветвь. Затем, когда пользователь тыркает + на раскрытие ветви выполняешь запрос на выбор БД, удаляешь пустую ветвь у выбранной, потом выполянешь запрос на выбор таблиц
Код

show tables;

И строишь подчиненную ветвь. 

Автор: KAMIKAZE 17.2.2011, 13:40
Цитата(Vas @  17.2.2011,  08:09 Найти цитируемый пост)
Ну когда запрос открыт перемещаешься по строкам выборки и добавляешь данные в TreeView.


Цитата(KAMIKAZE)

А как получать результаты его выполнения? Например даже я делаю запрос выборки всех полей, то как его считать, результат запроса?
   

Цитата(Vas @  17.2.2011,  08:09 Найти цитируемый пост)
Не могу, у меня нет компонентов UniDac.

Я конечно не могу просить их поставить  smile  но ведь это не трудно. smile 

Автор: Vas 17.2.2011, 14:08
KAMIKAZE, ты издеваешься, хоть бы выложил свои варианты, а то может ты и не пробуешь ничего делать. 
Да если не знаешь как по строкам выборки бегать, то я бы посоветовал бросить писать такие проги, как ты задумал, еще и с коннектом к разным БД. Запросы для получения таблиц, БД, и всего прочего у них абсолютно разные. В оракуле например нет понятия БД, там есть схемы и выбираются они совсем по-другому, не так как в MySQL.
Код

Procedure TFormDevice.ExpandLevel(const Node: TTreeNode);
var TreeNode:TTreeNode;
Begin
      try
        UniQuery1.Open;
      TVOs.Items.BeginUpdate; //Отключаем прорисовку ветки
       // Для каждой строки из полученного набора данных
      // формируем ветвь в TreeView, как дочерние ветки к той,
      // которую мы только что "раскрыли"
      First; //указатель на первую запись открытого набора
      while not Eof do //пока не дошли до конца открытого набора выполняем следующий код
        begin
          // Запишем в поле Data ветки ее идентификационный номер(ID) в таблице
          TreeNode:=TVOs.Items.AddChildObject(Node,
                    UniQuery1.FieldByName('Name').AsString+' ('+UniQuery1.FieldByName('Fulladr').AsString+')', Pointer(UniQuery1.FieldByName('ID').AsInteger));

          TreeNode.ImageIndex:=190; //картинка для ветки
          TreeNode.SelectedIndex:=180; //картинка для выделенной ветки
         // Добавим фиктивную (пустую) дочернюю ветвь только для того,
         // чтобы был отрисован [+] на ветке и ее можно было бы раскрыть
          TVOs.Items.AddChildObject(TreeNode, '', nil);
          Next; //переходим на следующую запись в наборе данных
         end; //while
      TVOs.Items.EndUpdate; //включаем прорисовку ветки
      except
          ShowMessage('Блин, ошибка в 17 строке');  
      end;
End;

Автор: KAMIKAZE 17.2.2011, 15:34
Я выложил что у меня получилось, самое последнее вложение DbTester.rar 770,10 Kb В нем не сразу обрабатывалось после открытия TRowDetailPanelEh. Дерево в нем еще не пытался делать, потому что ....

Цитата(Vas @  17.2.2011,  14:08 Найти цитируемый пост)
Да если не знаешь как по строкам выборки бегать, то я бы посоветовал бросить писать такие проги, как ты задумал

...Я вот и спрашиваю.  На яве это делается так http://www.kodejava.org/examples/280.html  А как на делфе не знаю.

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

Я знаю как работать с TreeView, но как получать те самые First и Next? В этом и вопрос.   


Автор: Vas 17.2.2011, 16:05
А причем тут Blob? 

Звиняюсь, процедура была с with переделывал уже когда вставил в форум
Код

Procedure TFormDevice.ExpandLevel(const Node: TTreeNode);
var TreeNode:TTreeNode;
Begin
      try
        UniQuery1.Open;
      TVOs.Items.BeginUpdate; //Отключаем прорисовку ветки
       // Для каждой строки из полученного набора данных
      // формируем ветвь в TreeView, как дочерние ветки к той,
      // которую мы только что "раскрыли"
      UniQuery1.First; //указатель на первую запись открытого набора
      while not Eof do //пока не дошли до конца открытого набора выполняем следующий код
        begin
          // Запишем в поле Data ветки ее идентификационный номер(ID) в таблице
          TreeNode:=TVOs.Items.AddChildObject(Node,
                    UniQuery1.FieldByName('Name').AsString+' ('+UniQuery1.FieldByName('Fulladr').AsString+')', Pointer(UniQuery1.FieldByName('ID').AsInteger));
          TreeNode.ImageIndex:=190; //картинка для ветки
          TreeNode.SelectedIndex:=180; //картинка для выделенной ветки
         // Добавим фиктивную (пустую) дочернюю ветвь только для того,
         // чтобы был отрисован [+] на ветке и ее можно было бы раскрыть
          TVOs.Items.AddChildObject(TreeNode, '', nil);
          UniQuery1.Next; //переходим на следующую запись в наборе данных
         end; //while
      TVOs.Items.EndUpdate; //включаем прорисовку ветки
      except
          ShowMessage('Блин, ошибка в 17 строке');  
      end;
End;


Здесь First и Next методы датасета.

Автор: KAMIKAZE 17.2.2011, 16:27
Цитата(Vas @  17.2.2011,  16:05 Найти цитируемый пост)
А причем тут Blob? 

На это не обращай внимания)   просто: while (resultSet.next()) { 

Вот теперь уже понятно  smile  Спасибо попробую.

Автор: KAMIKAZE 17.2.2011, 23:37
Чето не работает. Первое материться на   while not Eof do, ошибка I/O 6.  
Удалил фор, сделал просто

Код

UniQuery3.SQL.Clear;
UniQuery3.SQL.add('show databases');
UniQuery3.Open;
UniQuery3.First;
ShowMessage(UniQuery3.fieldbyname('Database').AsString);
UniQuery3.Next; //в принципе нет смысла писать)



Получаю имя первой базы. Ну а как пройтись по всем? Далее уже можно по ним делать выборки show tables in ...



Автор: Vas 18.2.2011, 09:14
Код

 while not UniQuery1.Eof do

Автор: KAMIKAZE 20.2.2011, 01:46
Все получилось. 

Выборка баз: 

Код

var TreeNode:TTreeNode;
begin

UniQuery3.SQL.Clear;
UniQuery3.SQL.add('show databases');
UniQuery3.Open;
UniQuery3.First;
while not UniQuery3.Eof do begin
TreeNode:=Form1.TreeView1.Items.AddChild(nil,UniQuery3.fieldbyname('Database').AsString);
TreeNode.HasChildren:=true; // "+" в ноде
TreeNode.ImageIndex:=0;
UniQuery3.Next;
end;


Далее выборка таблиц 

Код

procedure ShowTables(DatabaseNode: TTreeNode);
var node: TTreeNode;
begin
Form1.UniQuery3.SQL.Clear;
Form1.UniQuery3.SQL.Add('show tables in '+DatabaseNode.Text);
Form1.UniQuery3.Open;
form1.UniQuery3.First;
while not form1.UniQuery3.Eof do begin
node:=Form1.TreeView1.Items.AddChild(DatabaseNode,form1.UniQuery3.fieldbyname('Tables_in_'+DatabaseNode.Text).AsString);
Form1.UniQuery3.Next;
node.ImageIndex:=1;
node.SelectedIndex:=1;
end;
end;

procedure TForm1.TreeView1Expanding(Sender: TObject; Node: TTreeNode;
  var AllowExpansion: Boolean);
begin
if node.ImageIndex=0 then begin
TreeView1.Items.BeginUpdate;
Node.DeleteChildren;
ShowTables(Node);
TreeView1.Items.EndUpdate;     end;

end;




p.s.  вообще можно получать список баз не думая о запросе....
Код

var i:Integer; list: TStringList;
TreeNode:TTreeNode;
begin
list:=TStringList.Create;
UniConnection1.GetDatabaseNames(list);
for i:=0 to list.Count-1 do begin
TreeNode:=Form1.TreeView1.Items.AddChild(nil,list.Strings[i]);
TreeNode.HasChildren:=true;
TreeNode.ImageIndex:=0;
end;



И почему мне никто сразу не подсказал  smile    Жаль что нет метода UniConnection1.GetTableNames(), в который необходимо передавать название базы из которой необходима выборка таблиц.




Вопрос: при просмотре различных таблиц, ширина колонок плавает, иногда они очень мелкие, иногда широкие, непонятно от чего отталкивается их ширина. Как сделать по нормальному выравнивание? 




Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)