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

Вниз

Работа с ADO. Выделение параметров.   Найти похожие ветки 

 
И. Павел ©   (2010-06-24 09:10) [0]

Здравствуйте.

Пост получился длинным, так что основной вопрос я выделил жирным, на всякий случай :) Все остальное – просто дополнение к этому.

Я решил разобраться в том, как правильно работать с ADO. В частности, перешел на ADODataSet + ADOCommand вместо использования везде ADOQuery. Решил максимально применять параметры, чтобы избежать ряда трудностей. Ища в сети информацию про ADO, я натолкнулся на следующее:

1.
В сети встречаются темы, в которых обсуждают недостатки автоматического распознавания параметров: оно не дружит с табуляцией, иногда может воспринять за параметр не то двоеточие. А вот эта ошибка свидетельствует о нестабильной работе распознавания параметров:
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=62550

Да и вообще, какой смысл тратить время на то, чтобы парсировать запрос автоматически (для каждого запроса к SQL SERVER соединенние с сервером происходит дважды: при задании запроса и при его выполнении)? Вручную это делать удобнее и, похоже, надежнее. Насколько я понял, для этого нужно писать вместо параметров символ “?”. Но, т.к.OLE DB не поддерживает имена параметров, то важен порядок. Подскажите, пожалуйста, верно ли, что при работе через ADO с запросом любой сложности и уровнем вложенности к любой базе (MS SQL SERVER, Access и т.д.), проще говоря, всегда, AddParameter для создания параметров нужно вызывать в том же порядке, в каком идут знаки “?” слева-направо в CommandText?
Я написал модуль данных для работы с параметрами вручную (ParamCheck = false). Буду рад, если кто-нибудь согласиться его проверить.

2.
Вот еще это нашел в сети:
- “Использовать параметры правильным образом я боюсь после того, как дельфа стала съедать время от времени часть их длины. Именно поэтому я использую Query, а не StoredProc.” http://delphimaster.net/view/3-1263807978/
- “это нормально, что параметрический запрос отбрасывает хвост?” http://www.cyberforum.ru/delphi-beginners/thread112147.html

Ну это уже, ИМХО, очень сомнительные утверждения. Думаю, что это просто ошибки программистов, в которых они обвинили Delphi и ADO. Но все же хотелось бы знать: может действительно встречается что-то подобное? Хотя, думаю, если встречалось бы, про это бы говорили очень часто и в конце концов, исправили бы.


 
И. Павел ©   (2010-06-24 09:14) [1]

Я забыл указать путь к своему модулю: http://paste.org.ru/?w664j6
Пример работы с ним: http://paste.org.ru/?9wacbb


 
sniknik ©   (2010-06-24 09:38) [2]

> А вот эта ошибка свидетельствует о нестабильной работе распознавания параметров:
эта ошибка свидетельствует о глупости тех кто ее получает, не более... да еще и выводы.

а на самом деле в адо попросту НЕТ (а значит и не должно) возможности вносить запрос частями, только цельным, и сделано это частично и из-за того, что запрос подвергается обработке.
возьми например аналог, обрежь часть процедуры снизу, наполовину(/две трети как в ссылке) и попробуй скомпилить. получилось? ах какой дельфи глючный оказывается...

> Думаю, что это просто ошибки программистов, в которых они обвинили Delphi и ADO.
и не сомневайся. большинство ламеров так и делают. нормальные ищут ошибки там в последнюю очередь, когда и свой код уже перепроверен, и есть уверенность в том что изучил и понимаешь процесс.


 
И. Павел ©   (2010-06-24 09:54) [3]

Большое вам спасибо, sniknik ©.
Я, кстати, где-то находил информацию о том, что использовать Query.Add не желательно, но не смог соединить одно с другим :).
Тогда, раз ничего плохого в использовании автоматического парсирования нет, буду продолжать использовать его.
Вот и еще один плюс ADODataSet и AODCommand – там нет “Add”.


 
sniknik ©   (2010-06-24 11:32) [4]

плохого ничего нет. но мешать он иногда может, например если символ ":" часть запроса. случай довольно редкий (не в данных, т.к. их значения в параметрах и не влияют, а именно запроса)  но не невозможный (есть вызовы типа "SELECT * FROM ::fn_helpcollations()", или  "... FROM "LDAP:\\xxxx""). вот тут авто определение приходится отключать... ну а если в таком запросе нужны параметры то и делать их самому описывая в запросе вопросом, как ты хотел вначале.


 
Amoeba_   (2010-06-24 11:45) [5]


> И. Павел ©   (24.06.10 09:10)  

http://www.delphikingdom.com/asp/viewitem.asp?catalogid=733


 
И. Павел ©   (2010-06-24 12:28) [6]

sniknik ©, Amoeba_ спасибо.


 
12 ©   (2010-06-24 12:57) [7]

> что использовать Query.Add не желательно

моя просто из лени перестал использовать
прежде чем сделать add, надо делать clear
а *.text := "erwe"
делает сразу.


 
Anatoly Podgoretsky ©   (2010-06-24 14:41) [8]

> И. Павел  (24.06.2010 09:54:03)  [3]

Нет и поэтому нет кучи проблем с этим ADD


 
И. Павел ©   (2010-06-24 15:00) [9]

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

DMQ.ADOCon.BeginTrans;
try
 ADOC.CommandText := "CREATE TABLE tab1 (pole integer);";
 ADOC.Execute;
 ADOC.CommandText := "INSERT INTO tab1 (pole) VALUES (:TPole)";
 ADOC.Parameters.ParseSQL(ADOC.CommandText, true);
 with ADOC.Parameters.ParamByName("TPole") do
 begin
   DataType := ftInteger;
   Direction := pdInput;
   Value := 100;
 end;
 ADOC.Execute;
 //...
 //Прочие действия по обработке тех же и других данных
 //...
 DMQ.ADOCon.CommitTrans;
except
 DMQ.ADOCon.RollbackTrans;
 Application.MessageBox("Транзакция отменена", "Ошибка", 0);
end;


 
И. Павел ©   (2010-06-24 15:58) [10]

Кажется разобрался - все прекрасно работает. При парсировании второго запроса от базы даже приходит информация с типом только что созданного поля "pole", так что эта запись, наверное, даже более предпочтительна.

sniknik ©, Amoeba_ еще раз большое спасибо.


 
И. Павел ©   (2010-06-25 08:47) [11]

Итак, учитывая все мне уже известное про ADO, я написал примерный способ работы с ним, чтобы избежать подводных камней. Проверьте его, пожалуйста, и если нужно – дополните или укажите на ошибки.

1. Работа осуществляется через ADOCommand и ADODataSet, связанные с одним общим TADOConnection (за исключением случаев, когда нужно работать в нескольких потоках - тогда на каждый поток по своему ADOConnection).
2. Абсолютно все значения передаются через параметры
3. Табуляции и двоеточия, по возможности, не используются вообще
4. В CommandText за раз пишется по одной целой инструкции.
5. Если нужно выполнить транзакцию из нескольких инструкций (например несколько insert-ов) то делается BeginTrans, потом в CommandText пишется первая инструкция, делается Execute, потом, то же самое для второй, и т.д. до CommitTrans.

PS: В справке для TADOCommand нашел фразу: "One command may be executed at a time." А в русском варианте (http://www.znannya.org/?view=concept:124) ее перевели: "Способен за один раз исполнять одну и только одну команду". Подскажите, пожалуйста, это действительно важно, и если да, почему?


 
sniknik ©   (2010-06-25 09:38) [12]

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

> 3. Табуляции и двоеточия, по возможности, не используются вообще
с чего бы? в данных параметров они ни на что не влияют, а в составе запроса... если уж нужны то никуда от этого не деться.
какие то странные у тебя выводы.

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

> "One command may be executed at a time."
и что тут не ясного? движок может выполнять параллельные команды, а вот команда пока не отработает до конца не могут выполняться в то же время.


 
И. Павел ©   (2010-06-25 10:20) [13]

sniknik ©
Спасибо. Попробую использовать явные транзакции (это ведь BEGIN TRANSACTION/COMMIT/ROLLBACK?). Про недостатки BeginTrans/CommitTrans/RollBackTrans я не знал (похоже, у ADO полно странных сюрпризов...)

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


> и что тут не ясного?

Просто формулировку в справке можно понять так, что CommandText всегда должен содержать только одну инструкцию: "The TADOCommand component executes the command specified in its CommandText property. One command may be executed at a time." Вот я и хочу уточнить - так ли это. У меня MS SQL принимает цепочку инструкций из CommandText и выполняет.

Пункт 5 я просто не так сформулировал. Я имел ввиду, что, учитывая справку по ADOCommand, видимо лучше писать:

CommandText := "insert ...";
Execute;
CommandText := "insert ...";
Execute;
...


чем:

CommandText := "insert ... ; insert ... ; ...";
Execute;


Так ли это?


 
sniknik ©   (2010-06-25 10:43) [14]

> Про недостатки BeginTrans/CommitTrans/RollBackTrans я не знал (похоже, у ADO полно странных сюрпризов...)
не недостатки... блин.
просто, что думаешь будет при подключении к движку транзакций не поддерживающего? ничего не будет, а ты будешь уверен что у тебя все в ажуре.

ADO посредник, реальные действия выполняет движок/sql сервер. вот его ты и должен изучать.


 
И. Павел ©   (2010-06-25 11:07) [15]

> [14] sniknik ©   (25.06.10 10:43)

Ясно, спасибо.


 
Anatoly Podgoretsky ©   (2010-06-25 12:58) [16]

> И. Павел  (25.06.2010 10:20:13)  [13]

> У меня MS SQL принимает цепочку инструкций из CommandText и выполняет.

Но зараз только одну, затем другую


 
И. Павел ©   (2010-06-25 13:27) [17]

Anatoly Podgoretsky ©
Спасибо.



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

Форум: "Начинающим";
Текущий архив: 2010.09.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.015 c
2-1277272307
Cannon
2010-06-23 09:51
2010.09.19
Converter DBF to MDB


2-1277316263
ribos
2010-06-23 22:04
2010.09.19
В консоли ошибок нет, переношу под VCL вылетает исключение


15-1277287798
картман
2010-06-23 14:09
2010.09.19
Кто об этом писал?


15-1277317461
TStas
2010-06-23 22:24
2010.09.19
Почему с одного компа получается писать на форум, а с другого нет


2-1277281421
worldmen
2010-06-23 12:23
2010.09.19
Очистить все TComboBox на форме





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский