Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Incorrect Syntax на одной машине, а на другой — все работает...


Страницы:   1 2 3

И. Павел ©   (2011-12-15 10:51:00) 

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

У меня есть сервис (код обработчика onExecute в конце этого сообщения).
На моем компьютере (Windows 7, 32 бита) сервис работает нормально. Но после запуска его на сервере (Windows 2003 server) выводится ошибка.
Запрос SELECT выполняется на обоих компьютерах. Но большой запрос with ... delete ... inner join ... inner join ... возвращеет ошибку: incorrect syntax near the keyword with (повторюсь — на моем компьютере все работает).
Сервер БД: MS SQL SERVER 2005.

Если бы ошибка была connection failure и т.п., то все было бы ясно.
Но ведь сначала мой сервис на компьютере-сервере запускается, коннектится к базе, делает SELECT, использует полученную информацию и уже потом, выполняя with ... delete ... выводит ошибку парсирования.

Подскажите, пожалуйста, из-за чего может произойти incorrect syntax, если на другой машине все было нормально. На всякий случай переустановил MDAC SDK (подозревал, что может-быть MDAC пытаестя делать опережающее парсирование, чтобы не отсылать данные серверу, сразу вылавливать синтаксические ошибки в запросах и что MDAC не понял, что такое «with», т.к. этой конструкции нет в 2000 сервере).

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

Если нужна более подробная информация — пишите что нужно сообщить — сообщу.

Заранее спасибо.

1. Вот код OnExecute (урезанный, т.к. дальше ShowPosDoc1 дело не доходит):

procedure TSEDDeloMonitoringYITService2.ServiceExecute(Sender: TService);
var SleepInterval: integer;
   d: TDateTime;
begin
 try
   PrepareReg; //регистрирую путь этой службы, чтобы из ее ресурсов доставался шаблон для строки в службе сообщений windows

   CoInitialize(nil);  
   DMQ.Connect('');

   ADODS.Active := false;
   ADODS.CommandText := 'SELECT interval, MailInterval FROM USERLIST.dbo.MonConfig;'; //прекрасно срабатывает
   DMQ.Open;

   MailThread := TMailThread.Create(false);

   while (not Terminated) do
   begin

     if MailThread.Finished then
       break;

     d := now;

     ShowPosDoc1;
     ServiceThread.ProcessRequests(false);
     if Terminated then break;

     //тут еще ряд таких же блоков, как и выше  (вызов функции, ProcessRequest, проверка остановки)

     //потом идет цикл с ожиданием, но до него выполнение не доходит  
   end;

   MailThread.Terminate;
   MailThread.WaitFor;

   CoUninitialize;
 except
   on e: Exception do
   begin
     ExceptHandler(e);
   end;
 end;
end;


DiamondShark   (2011-12-15 19:50:00) [1]


> Ega23 ©   (15.12.11 16:51) [55]

При чём тут пул коннектов?


Ega23   (2011-12-15 16:51:00) [2]


> Пользы от совместного использования коннекта -- чуть менее,
>  чем никакой.
> Ну и нафиг такое счастье нужно? Чистапаржать?


Отнюдь. Пул коннектов, как вполне обычный пример.


OW   (2011-12-15 16:47:00) [3]


> DiamondShark ©   (15.12.11 16:42) [51]
> > Сам поток не создает соединение, но каждый поток работает
> > со своим соединением.
> Аккуратно разложенные грабельки.


?


OW   (2011-12-15 16:47:00) [4]


> Необходимо в таком случае как-то узнать что коннекшин свободен,
>  и назначить его другому потоку

мессагой
шлем мессагу, что я все, забирай.
шлем мессагу с Wпараметром = указателю на соединение кому то другому, он в курсе, берет MyConnection := TConnection(парам) и вперед.


stas   (2011-12-15 16:44:00) [5]

OW ©   (15.12.11 16:41) [50]

Зависит конечно от приложения, но так сложнее
Необходимо в таком случае как-то узнать что коннекшин свободен, и назначить его другому потоку.


DiamondShark   (2011-12-15 16:42:00) [6]


> Сам поток не создает соединение, но каждый поток работает
> со своим соединением.

Аккуратно разложенные грабельки.


OW   (2011-12-15 16:41:00) [7]

А зачем уничтожать соединение?
Создал сразу 5 (или максимум возможных сервером) соединений.
Стартанул поток - дал ему соединение, закончился поток, считаем свободным, дадим еще кому-то потом
Пул этакий


Anatoly Podgoretsky   (2011-12-15 16:38:00) [8]

> Ega23  (15.12.2011 16:13:39)  [39]

Ну для того что бы получать ошибки и тогда возмущение будет справедливым,
Микрософт маст дай


DiamondShark   (2011-12-15 16:37:00) [9]


> Ega23 ©   (15.12.11 16:13) [39]
> Речь о другом: почему экземпляр класса TADOConnection должен
> создаваться "внутри" другого треда?

А кто сказал, что должен? Создавай где хочешь. Только если у тебя создание и использование экземпляра в разных потоках, то принимай во внимание, как минимум, маршалинг. Даже местные знахари иногда попадаются в ловушку: если у тебя STA и межпоточные вызовы -- будь добр запилить message pump.

Даже если у тебя всё обойдётся с COM-маршалером, то многие провайдеры не поддерживают несколько активных команд на одном соединении (MSSQL именно такой).

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

Пользы от совместного использования коннекта -- чуть менее, чем никакой.
Ну и нафиг такое счастье нужно? Чистапаржать?


stas   (2011-12-15 16:33:00) [10]

OW ©   (15.12.11 16:29) [46]

не пойму смысла?
создал в потоке, при уничтожении потока и уничтожил конекшин.
А как следить за экземплярами конекшинов.


OW   (2011-12-15 16:29:00) [11]

Ну, сам придерживаюсь такой тактики

Создать соединение можно где угодно(у меня обычно приложение их создает), а работать каждый поток должен со своим, отдельным соединением (поток получает его при старте)
т.е.
Сам поток не создает соединение, но каждый поток работает со своим соединением.


Ega23   (2011-12-15 16:28:00) [12]


> ты это имеешь ввиду?


Не только.


знайка   (2011-12-15 16:24:00) [13]


> Но у меня в коде до «with...delete...» нет ни одного оператора
> вставки.
Это не важно, главне что сервер получает, профайлер бы показал.


stas   (2011-12-15 16:23:00) [14]

stas ©   (15.12.11 16:22) [42]
*создать и обращаться из разных потоков


stas   (2011-12-15 16:22:00) [15]

Ega23 ©   (15.12.11 16:15) [40]
В принципе если конекшин создать в разных потоках, то в этом нет ничего страшного при условии если к нему не обращаться одновременно из нескольких потоков.

ты это имеешь ввиду?


stas   (2011-12-15 16:19:00) [16]

Anatoly Podgoretsky ©   (15.12.11 16:13) [38]

А я о чем?
4. Connection лучше создать в том же потоке из которого вы к нему обращаетесь как и command

Ega23 ©   (15.12.11 16:15) [40]
так и что я неправильно написал?


Ega23   (2011-12-15 16:15:00) [17]


> stas ©   (15.12.11 16:11) [37]
>
> Ну, так и есть.


Это несколько отличается от твоего поста:
4. Connection лучше создать в том же потоке из которого вы к нему обращаетесь как и command


Ega23   (2011-12-15 16:13:00) [18]


> COM-Объекты ADO работают в STA модели.


Это всё прекрасно.
Речь о другом: почему экземпляр класса TADOConnection должен создаваться "внутри" другого треда?


Anatoly Podgoretsky   (2011-12-15 16:13:00) [19]

> stas  (15.12.2011 16:11:37)  [37]

AdoConnection должно быть 5 штук.


stas   (2011-12-15 16:11:00) [20]

Ega23 ©   (15.12.11 16:05) [34]
Ну, так и есть.
Зачем изначально закладывать в программу, то с чем могут быть проблемы, я понимаю когда это действительно необходимо можно дописать критикал секции и т.д.

stas ©   (15.12.11 16:01) [32]
Эта ошибка при одновременном обращении к комманду.

А вот в случае с AdoConnection вроде как и ошибок не возникает, но и не происходит должных операций. При том что если хочется узнать @@Identity (в случае с Access) то вернется id последней вставки выполненной через данный AdoConnection, т.е. в потоке A можно получить ID потока B.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо