Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.03.20;
Скачать: [xml.tar.bz2];

Вниз

Книга по 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.007 c
2-1293424349
Curse
2010-12-27 07:32
2011.03.20
Растолкуйте пожалуйста безъязыкому


1-1248801245
Sergey
2009-07-28 21:14
2011.03.20
Ищу функцию, чтобы рисовать на картинке формулы с дробью


2-1293449561
сергей2010
2010-12-27 14:32
2011.03.20
Удаление записей из файла


15-1291469704
xayam
2010-12-04 16:35
2011.03.20
Трансляция шахматных партий


2-1293131507
nza
2010-12-23 22:11
2011.03.20
Как отлаживать компонент?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский