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

Вниз

Книга по ADO для не совсем чайника   Найти похожие ветки 

 
ProgRAMmer Dimonych ©   (2010-11-22 22:13) [0]

Хочу наконец-то взяться за освоение ADO в Delphi. С базами данных до этого работал связкой PHP+MySQL, успешно. Возникает куча проблем с тем, чтобы выбирать этих провайдеров, размещать БД и т.п. Гугление по теме даёт мало полезного.

Очень хотелось бы получить ссылки на книжки, где нет тупого перечисления свойств Delphi-йских компонентов и копипасты с учебника по реляционным БД, а описаны конкретно особенности использования ADO, то, как правильно настроить его для конкретной задачи.

Заранее благодарен.


 
sniknik ©   (2010-11-22 22:37) [1]

противоречивые требования... конкретно особенности, и вдруг для конкретной задачи...

нет такого. особенности, и настройки/описание обычно идут отдельно от конкретики. файл справки ADO210.CHM на твоем же компе, там и особенности и настройки, но естественно без конкретных задач.

> Гугление по теме даёт мало полезного.
гугление дает ВСЕ, главное правильно выбрать ключевые слова.


 
ProgRAMmer Dimonych ©   (2010-11-22 22:53) [2]

ОК. Гугл в частности выкинул на учебник на 256bit.ru. Где просто перечисляются объекты и их свойства. Этакая копипаста со справки. Остальное - обрывки. Ну, и ссылки на Фленовскую "Библию Delphi", но, помнится, не слишком лестные об этом авторе отзывы здесь были в своё время.


 
MsGuns ©   (2010-11-23 00:21) [3]

Насколько знаю, исчерпывающего пособия по АДО нет и не может быть в принципе, т.к. это не  СУБД, а всего лишь технология,  инструмент, набор компонент.

Но есть, однако несколько "путеводных" :)
1) Стандарт SQL, надо понимать, относящися к конкретной СУБД, см. соотв. мануалы к серверам
2) Строка подключения - ищи в инете ресурсы с ключевым словом ConnectionString. Ну и по форумам.
3) Особенности именно дельфишных компонент. Ничего лучше справки не видел, ну еще опыт, конечно. Очень может помочь поиск по этому сайту, в частности ремарки SnikNik, пожалуй, главного спеца в этой области на данном ресурсе.

А вообще лучше всего изучать АДО не вообще, а применительно к конкретному серверу, ИМХО, лучше всего к MS SQL Server


 
MsGuns ©   (2010-11-23 00:24) [4]

Я сейчас дома сижу в основном, можешь стучаться в асю по мере надобности, а сорсу слать на мыло. И то, и другое есть в анкете.
Опыт у меня в основном по мсскл и немного по акцесу
Могу выслать библиотеки свои, где много наваено именно для АДО


 
MsGuns ©   (2010-11-23 00:28) [5]

Фленова, Архангельского, Фаронова - сразу фтопку !


 
MsGuns ©   (2010-11-23 00:36) [6]

Вот по строке нашел (такой сложный урл :) )
http://www.connectionstrings.com/


 
Дмитрий Тимохов   (2010-11-23 16:02) [7]

ADODB пользуюсь 10 лет, но еще тогда был вынужден отказаться от дельфишных компонент - они не умеют работать с типом TDecimal (тип MSSQL-Server"а Decimal(28,10). Такой тип у нас есть в БД.

Вернее, они умеют, но преобразовывают TDecimal в Double или Exctended. Если интересно, то могу посмотреть в деталях. На этот счет даже в Quality Central уже лет 8 лежит соотв. запрос на доработку.

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

Если особо не вдаваться в специфические функции ADODB (асинхронность, серверные курсоры и т.д.), то там все просто, я считаю.

У меня за все время только одна проблема была с ADODB. Но я думаю, что это скорее проблема MSSQL. Справился не очень красиво, но работает - иначе не смог. Вот мой коммент по этому поводу. Может полезно будет.

  // В ходе эксплуатации было установлено, что в некоторых
  // случаях в ходе выполнения сложной сохраненной
  // процедуры происходит ее перекомпиляция (суд по профайлеру),
  // что приводит к тому, что возвращается 2 рекордсета -
  // первый пустой, а второй - с данными.
  // Поиск причин подобного поведения не дал результатов.
  // Поэтому было принято решение в тех случаях,
  // где предполагается наличие рекордсета
  // искать первый открытый рекордсет и его возвращать.
  // Вот если такой рекордсет не найден возвращать ошибку.


 
Sergey Masloff   (2010-11-23 17:13) [8]

Вот как раз готовил на выкид книжки - есть А.Федоров - Н.Елманова "ADO в Delphi" изд. 2000 год ISBN 5-94157-098-8  790 страниц, CD в комплекте. Состояние как новая.

Отдам за бутылку хорошего пива. Предложение действительно до пятницы - в субботу выкину.


 
Дмитрий Тимохов   (2010-11-23 17:55) [9]

А за 2 бутылки, Сергей, можешь отдашь сети Оланда? :)))


 
sniknik ©   (2010-11-23 18:12) [10]

> что приводит к тому, что возвращается 2 рекордсета -
> первый пустой, а второй - с данными.

UPDATE Action SET Name="" WHERE Name=""
SELECT * FROM Action


Выполнено применительно к 0 записям. (no recordset)
               применительно к 16 записям

т.е. 2 рекордсета, один пустой, другой с данными. (рекордсет он не только для данных, там еще и ошибки возвращаются, информация ... кому не нужно должен пропускать)

или -


SET NOCOUNT ON
UPDATE Action SET Name="" WHERE Name=""
SELECT * FROM Action
SET NOCOUNT OFF


Выполнено применительно к 16 записям

т.е. 1 рекорсет, только данные.


 
Дмитрий Тимохов   (2010-11-23 18:54) [11]


> sniknik ©   (23.11.10 18:12) [10]

Ну ты эта, за новичка не держи.

Мы неделю сидели в глубокой отладке в профайлере.

Процедура по сама собой при своем выполнении перекомпилировалась.

Т.е. сама в ходе работы останавливалась, потом строила новый план, потом снова выполнялась. Вот с первого раза возвращался пустой роусет.

Я понимаю, что это специфично. Но мы на это неделю угорохали. Так и не нашли причину.


 
MsGuns ©   (2010-11-23 19:02) [12]

>Дмитрий Тимохов   (23.11.10 18:54) [11]
>Процедура по сама собой при своем выполнении перекомпилировалась.
>Т.е. сама в ходе работы останавливалась, потом строила новый план, >потом снова выполнялась.

Работали по ночам ? Декалитры кофе, батареи сигарет ?
Это ничего, бывает.  Рецепт простой - здоровый продолжительный сон


 
sniknik ©   (2010-11-23 19:44) [13]

> Процедура по сама собой при своем выполнении перекомпилировалась.
повторить сможешь? или хотя бы после бэкап, ресторе, на другом сервере повторяется?


 
sniknik ©   (2010-11-23 19:46) [14]

> Вот с первого раза возвращался пустой роусет.
вам бы с него ошибку считать, может быть и прояснилось чего.


 
Sergey Masloff   (2010-11-23 20:42) [15]

Дмитрий Тимохов   (23.11.10 17:55) [9]
Дим да я бесплатно тебе ее отдам если найду. Не пойму все перерыл уже :(


 
Дмитрий Тимохов   (2010-11-23 21:10) [16]


> sniknik ©   (23.11.10 19:46) [14]
>
> > Вот с первого раза возвращался пустой роусет.
> вам бы с него ошибку считать, может быть и прояснилось чего.
>


А как с роусета читать ошибку, если он пустой и закрытый?
Просвети.


 
KSergey ©   (2010-11-23 21:22) [17]

По-моему, про ADO самое полезное - это цикл из 3-х статей
http://delphikingdom.ru/asp/viewitem.asp?catalogid=408
и далее по ссылкам в конце каждой части (всего их три).


 
sniknik ©   (2010-11-23 21:38) [18]

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

вот, один из вариантов, ближе тебе если не используешь обертки.
procedure TForm1.Button4Click(Sender: TObject);
var
 cmd: _Command;
 Conn: _Connection;
 Pars: Parameters;
 RA: OleVariant;
 rs: _Recordset;
 n: Integer;
begin
 Conn:= CreateComObject(CLASS_Connection) as _Connection;
 Conn.ConnectionString:= Edit1.Text;
 Conn.Open(Conn.ConnectionString, "", "", Integer(adConnectUnspecified));

 cmd:= CreateComObject(CLASS_Command) as _Command;
 cmd.CommandType:= adCmdText;
 Conn.CursorLocation:= adUseServer;
 cmd.Set_ActiveConnection(Conn);

 cmd.CommandText:= RichEdit1.Lines.GetText;
 rs:= cmd.Execute(RA, 0, Integer(adCmdText));
 while rs <> nil do begin
   for n:= 0 to (Conn.Errors.Count-1) do
     Memo1.Lines.Add(Conn.Errors.Item[n].Description);
   rs:= rs.NextRecordset(RA);
 end;

 cmd.Set_ActiveConnection(nil);      
 Conn.Close;
 Pars:= nil;
 cmd:= nil;
 Conn:= nil;
end;


проверить можно например PRINT-ом (в mssql это та же ошибка только низкого уровня (типа abort в делфи))


 
Дмитрий Тимохов   (2010-11-24 09:46) [19]


> sniknik ©   (23.11.10 21:38) [18]
>
> > если он пустой и закрытый?
> он не может быть закрытым, ведь он вернулся, и следующим
> за ним идет с данными... сам сказал.
>


Вот именно закрытый приходит.
Я его так достаю:


  kAdoDb_Recordset := fAdoDb_Command.Execute(kRecordsAffected, EmptyParam, adCmdUnspecified);
  while (kAdoDb_Recordset <> nil) and (kAdoDb_Recordset.State <> adStateOpen) do
     kAdoDb_Recordset := kAdoDb_Recordset.NextRecordset(kRecordsAffected);
  Assert(kAdoDb_Recordset <> nil, "Запрос не вернул таблицу данных!");


Ладно, это в общем специфика, видимо, моя. В настоящий момент не актуальная. Запишу как дело посмотреть детальней, когда время будет - может правда в ошибках приходит что-то?

А вопрос к тебе вот какой - как проставить Recordset.CursorType, если пользуешься для его получения Command.Execute?

Я тут озадачился, а какой у меня CursorType - оказалось, что статик (умолчательное значение). А мне и ForwardOnly подошел бы. Хочу его поставить, но не пойму как.


 
MsGuns ©   (2010-11-24 15:22) [20]

Курсор выставляется у соединения. Причем ДО его установления


 
Дмитрий Тимохов   (2010-11-24 17:24) [21]


> MsGuns ©   (24.11.10 15:22) [20]
>
> Курсор выставляется у соединения. Причем ДО его установления


Неа, CursorLocation устанавливается у соединения, CursorType у Recordset - либо в свойстве CursorType, либо в методе Open.

А вот если я пользуюсь не Recordset.Open, а Command.Execute. Тады как?


 
Anatoly Podgoretsky ©   (2010-11-24 18:52) [22]

Чего ой?


 
Дмитрий Тимохов   (2010-11-24 18:55) [23]


> Anatoly Podgoretsky ©   (24.11.10 18:52) [22]
>
> Чего ой?

Это кому? )


 
Anatoly Podgoretsky ©   (2010-11-24 19:02) [24]

> Дмитрий Тимохов  (24.11.2010 18:55:23)  [23]

А кто ойкает?


 
Дмитрий Тимохов   (2010-11-24 19:06) [25]


> Anatoly Podgoretsky ©   (24.11.10 19:02) [24]
>
> > Дмитрий Тимохов  (24.11.2010 18:55:23)  [23]
>
> А кто ойкает?


ты о чем конкретно?
я в чем-то не прав?

 Connection15 = interface(_ADO)
   ...
   function  Get_CursorLocation: CursorLocationEnum; safecall;
   procedure Set_CursorLocation(plCursorLoc: CursorLocationEnum); safecall;

 Recordset15 = interface(_ADO)
   ...
   function  Get_CursorType: CursorTypeEnum; safecall;
   procedure Set_CursorType(plCursorType: CursorTypeEnum); safecall;


Собственно и вопрос, как поставить этот CursorType, если для получения Recordset я использую метод

  Command15 = interface(_ADO)
     ...    
     function  Execute(out RecordsAffected: OleVariant; const Parameters: OleVariant; Options: Integer): _Recordset; safecall;


 
MsGuns ©   (2010-11-24 19:28) [26]

>Дмитрий Тимохов   (24.11.10 17:24) [21]
>Неа, CursorLocation устанавливается у соединения, CursorType у Recordset ->либо в свойстве CursorType, либо в методе Open.

Да, конечно, невнимательно прочитал. Извини

>А вот если я пользуюсь не Recordset.Open, а Command.Execute. Тады как?

Дык это не одно и то же ?
Command.Execute возвращает 1-й рекордсет, если он есть или нил, разве не так ?


 
MsGuns ©   (2010-11-24 19:31) [27]

>Я тут озадачился, а какой у меня CursorType - оказалось, что статик
>(умолчательное значение). А мне и ForwardOnly подошел бы. Хочу его >поставить, но не пойму как.

А зачем собственно. Что, здоровый НД возвращается и тормоза при перемещении ? Не проще ли просто конкретизировать запрос, уменьшая к-во выбираемых записей ?


 
MsGuns ©   (2010-11-24 19:33) [28]

Вдогонку. Если курсор не серверный, не один ли фиг, двунаправленный он или однонаправленный ? Или курсор все же на сервере ?


 
Дмитрий Тимохов   (2010-11-24 19:43) [29]


>
> Дык это не одно и то же ?
> Command.Execute возвращает 1-й рекордсет, если он есть или
> нил, разве не так ?


ну в общем не одно и то же )
Command.Execute он же может выполнять запрос с параметрами (отсюда сохранение плана запроса для будущих нужд и прочие хорошие вещи), а Recordset.Open - нет.


> А зачем собственно. Что, здоровый НД возвращается и тормоза
> при перемещении ? Не проще ли просто конкретизировать запрос,
>  уменьшая к-во выбираемых записей ?


Не, ну написано в справке, что Forward Only работает быстрее, значит им надо пользоваться. Все равно мне только в одну сторону надо бегать.

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


> Вдогонку. Если курсор не серверный, не один ли фиг, двунаправленный


Курсор клиентский. Серверными не пользуемся.


 
Плохиш ©   (2010-11-24 20:06) [30]


> Дмитрий Тимохов   (24.11.10 19:43) [29]


> Не, ну написано в справке, что Forward Only работает быстрее,
>  значит им надо пользоваться.


> Курсор клиентский. Серверными не пользуемся.

В моей справке ещё написано

Hinweis: Wenn die Eigenschaft CursorLocation der ADO-Datenmenge den Wert clUseClientOnly hat, wird nur die Konstante ctStatic unterst&#252;tzt.


 
Дмитрий Тимохов   (2010-11-24 20:15) [31]


> Hinweis: Wenn die Eigenschaft CursorLocation der ADO-Datenmenge
> den Wert clUseClientOnly hat, wird nur die Konstante ctStatic
> unterst&#252;tzt.

да все понятно:

Примечание: Если имущество CursorLocation набор данных ADO имеет значение clUseClientOnly поддерживается только постоянным ctStatic.

Ну и не надо нам Forward Only.
Я все равно собираюсь переделывать так (так быстрее процентов на 30 загружается):

var
  kRows: OleVariant;
  kRow: Integer;
  kRecordCount: Integer;
begin
  kRS := SomeCommand.Execute(...);
  kRecordCount := kRS.RecordCount;
  kRows := kRS.GetRows(kRecordCount, adBookmarkFirst, VarArrayOf(["Field1", "Field2"]));
  for kRow := VarArrayLowBound(kRows, 2) to VarArrayHighBound(kRows, 2) do
  begin
     kField1 := kRows[0, kRow];
     kField2 := kRows[1, kRow];
     ...
  end;


 
Игорь Шевченко ©   (2010-11-24 20:18) [32]

Дмитрий Тимохов   (24.11.10 20:15) [31]

dbExpress не проще ? Оно точно в одну сторону


 
Дмитрий Тимохов   (2010-11-24 20:21) [33]


> dbExpress не проще ? Оно точно в одну сторону

я еще не изучил.

ладно, вопрос по ADO снимается в силу:
> Hinweis: Wenn die Eigenschaft CursorLocation der ADO-Datenmenge
> den Wert clUseClientOnly hat, wird nur die Konstante ctStatic
> unterst&#252;tzt.

Я, видимо, в 2001 году и не сделал Forward, т.к. прочел эту документацию.


 
sniknik ©   (2010-11-25 08:55) [34]

> Я все равно собираюсь переделывать так (так быстрее процентов на 30 загружается):
очень странно. присвоение готового рекордсета (ссылки) vs копирование его в массив, и копирование выигрывает? что то не то в датском королевстве (не ADO имею в виду).


 
Дмитрий Тимохов   (2010-11-25 09:41) [35]


> sniknik ©   (25.11.10 08:55) [34]
>
> > Я все равно собираюсь переделывать так (так быстрее процентов
> на 30 загружается):
> очень странно. присвоение готового рекордсета (ссылки) vs
> копирование его в массив, и копирование выигрывает? что
> то не то в датском королевстве (не ADO имею в виду).


А ты попробуй десятка два Мб скачать. Понимаю, что для реальной задачи - нонсенс, но для опыта пойдет.
мой код быстрее, нежели просто Recordset.MoveNext.
Сам был удивлен. Мне этот код подсказал наш базаданщик - он его на SQL.RU где-то подсмотрел.

Ну, может, не 30, а 20. Но быстрее.


 
Игорь Шевченко ©   (2010-11-25 10:19) [36]


> А ты попробуй десятка два Мб скачать.


Дружный смех в зале


 
Дмитрий Тимохов   (2010-11-25 11:06) [37]


> Игорь Шевченко ©   (25.11.10 10:19) [36]
> > А ты попробуй десятка два Мб скачать.
> Дружный смех в зале


А что здесь такого? А если это отчет на 838389389389389 страниц?
Или ты отчеты не строишь?


 
Игорь Шевченко ©   (2010-11-25 12:23) [38]


> А что здесь такого?


объемы небольшие.


 
Дмитрий Тимохов   (2010-11-25 12:27) [39]

мы не обсуждаем объемы, мы обсуждаем подход к чтению рекордсета в ADODB.

у тебя вообще оракл )


 
Игорь Шевченко ©   (2010-11-25 13:12) [40]


> у тебя вообще оракл )


и ADO я не пользуюсь



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

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

Наверх




Память: 0.58 MB
Время: 0.02 c
2-1293381154
cross
2010-12-26 19:32
2011.03.20
обрезается строка (string)


2-1293407915
Тимоха111
2010-12-27 02:58
2011.03.20
динамический pagecontol и событие к нему


15-1290557577
RGV
2010-11-24 03:12
2011.03.20
Кто нибудь изучал как рисует AlphaSkin прозрачный бордюр формы и


2-1293141411
adigozelov
2010-12-24 00:56
2011.03.20
IP address user


4-1246533531
ruben
2009-07-02 15:18
2011.03.20
Не вызываются события при работе с tapi