Форум: "Прочее";
Текущий архив: 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ü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ü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ü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.006 c