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