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

Вниз

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

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

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

У меня есть сервис (код обработчика 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;


 
OW ©   (2011-12-15 11:52) [1]

сам запрос, текст?
пользователь, сервер -  тот же?
в пределах сессии нет явных модификаторов этой сессии? (SET ЧТО-ТО ON|OFF)


 
знайка   (2011-12-15 11:52) [2]

Перед with поставте ;.


 
Anatoly Podgoretsky ©   (2011-12-15 12:08) [3]

> И. Павел  (15.12.2011 10:51:00)  [0]

С MS SQL идет профилировщик, посмотри какие запросы поступают с каждой
машины.


 
stas ©   (2011-12-15 13:25) [4]

1.какой релиз MSSQL? на серверную винду и на обычную одинаковый релиз может не стать.
2. какая строка подключения? используйте Native client.
3. протокол tcp, namepipes?
4. Connection лучше создать в том же потоке из которого вы к нему обращаетесь как и command
5. покажите тот большой запрос


 
Ega23 ©   (2011-12-15 13:35) [5]


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


Докажи.


 
И. Павел ©   (2011-12-15 13:46) [6]

> знайка, Anatoly Podgoretsky ©

Большое спасибо. Дело действительно было в этом. Что-то внутреннее, видимо, посылается вместе с запросом самим драйвером. &laquo;;&raquo; помогла.


> [4] stas ©   (15.12.11 13:25)

Спасибо за интерес к проблеме.

Пользователь и сервер &#151; одинаковые. Явных модификаторов сессии нет. Подключаюсь через OLEDB. Connection в том же потоке. MS SQL SERVER стоит на отдельном сервере. А мои клиенты &#151; на клиенте и на другом сервере, т.е. MS SQL SERVER общий для всех.


 
И. Павел ©   (2011-12-15 13:49) [7]

> [1] OW ©   (15.12.11 11:52)

Тоже спасибо за интерес к проблеме. Ответы на вопросы в [6].


 
И. Павел ©   (2011-12-15 13:51) [8]

В итоге, получается, нужно все запросы начинать с точки с запятой?
Или только запросы ADOCommand, а запросы ADODataSet просто так отправлять?
Это же получается недоработка ADO или OLEDB? Или так и предполагалось, что нужно всегда ставить точку с запятой? Или предполагалось, что парсер всегда разберет начало новой команды, но не расчитывали на предложение &laquo;With&raquo;?


 
sniknik ©   (2011-12-15 14:02) [9]

> В итоге, получается, нужно все запросы начинать с точки с запятой?
начинать? нет. заканчивать.


 
stas ©   (2011-12-15 14:10) [10]

>Ega23 ©   (15.12.11 13:35) [5]
Зачем? если кто-то сомневается - его проблемы.


 
Anatoly Podgoretsky ©   (2011-12-15 14:22) [11]

Что так и будешь гадать или все таки посмотришь профайлером.


 
Palladin ©   (2011-12-15 14:24) [12]


> stas ©   (15.12.11 14:10) [10]

Я не то что бы сомневаюсь, у меня просто это далеко не так. Сопсна и проблем то нет.


 
Ega23 ©   (2011-12-15 14:34) [13]


> Зачем? если кто-то сомневается - его проблемы.


LMD


 
Медвежонок Пятачок ©   (2011-12-15 14:43) [14]

Подключаюсь через OLEDB.

бат уай?!

найтив клиент же нативнее.


 
stas ©   (2011-12-15 14:44) [15]

LMD  это что?


 
Anatoly Podgoretsky ©   (2011-12-15 14:45) [16]

> stas  (15.12.2011 14:44:15)  [15]

> LMD  это что?

Это не хорошо


 
OW ©   (2011-12-15 14:51) [17]

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


 
stas ©   (2011-12-15 14:55) [18]

Palladin ©   (15.12.11 14:24) [12]

Может быть так или не так, а как это далеко не так? )

Берем кладем на форму AdoConnection, AdoCommand.
Создаем Thread в котором выполняем вставку в БД в цикле до 10000 используя тот же AdoCommand.
По кнопке запускаем поток - все замечательно
теперь создаем 5 экземпляров того же потока, запускаем...


 
Anatoly Podgoretsky ©   (2011-12-15 15:20) [19]

> stas  (15.12.2011 14:55:18)  [18]

О боже, в базе стало 50000


 
stas ©   (2011-12-15 15:29) [20]

Anatoly Podgoretsky ©   (15.12.11 15:20) [19]
Не правильно.


 
Ega23 ©   (2011-12-15 15:30) [21]


> теперь создаем 5 экземпляров того же потока, запускаем..


И?


 
Ega23 ©   (2011-12-15 15:32) [22]


> Не правильно.


С какого перепуга?


 
Dennis I. Komarov ©   (2011-12-15 15:43) [23]

Сперва создадим проблемы, потом героически их будем решать...


 
OW ©   (2011-12-15 15:44) [24]


> Берем кладем на форму AdoConnection, AdoCommand.
> Создаем Thread в котором выполняем вставку в БД в цикле
> до 10000 используя тот же AdoCommand.
> По кнопке запускаем поток - все замечательно
> теперь создаем 5 экземпляров того же потока, запускаем..

Усложним задачу,
Первый поток вставляет 1 в поле INT_VAL, второй - 2, и т.п.
N-ый поток обнаружил ошибку и хочет откатить.

Что откатится?


 
И. Павел ©   (2011-12-15 15:50) [25]

> начинать? нет. заканчивать.

Но у меня в коде до &laquo;with...delete...&raquo; нет ни одного оператора вставки. Единственное, что я выполняю в явном виде &#151; SELECT. Но он заканчивается на &laquo;;&raquo;. Получается, это все-таки недоработка среды, которую приходится компенсировать? В запросах ADODataSet такое не встречается? Т.е. там &laquo;;&raquo; в начале поставить можно, но как-то боязно: не понятно, что будет возвращаться в DataSet.


> [11] Anatoly Podgoretsky ©   (15.12.11 14:22)
> Что так и будешь гадать или все таки посмотришь профайлером.

Нельзя. Почему что в последнее использование поток профайлера администраторам удалось сбить только перезагрузив всю систему. Так что мне сказали &#151; если можно то лучше им не пользоваться...


 
Ega23 ©   (2011-12-15 15:50) [26]


> Усложним задачу,


Да зачем? Не, ну если товарищ не знает ничего про объекты синхронизации и обращается к одним данным, а также изменяет их, из разных тредов и не боится косяков, то...


 
stas ©   (2011-12-15 15:52) [27]

Ega23 ©   (15.12.11 15:32) [22]

> Не правильно.

С какого перепуга?

Ну хотя бы с того что если следовать вашей логике то их будет 6000 )

Да и почитайте эту ветку, с этого же сайта
http://delphimaster.net/view/3-1162214995


 
И. Павел ©   (2011-12-15 15:53) [28]

> Нельзя. Почему что в последнее использование поток профайлера
> администраторам удалось сбить только перезагрузив всю систему.
> Так что мне сказали — если можно то лучше им не пользоваться...

А к этой базе привязана система, которую используеет почти каждый сотрудник, имеющий компьютер. И не кто из админов не в курсе, почему в тот раз обычный запуск профайлера все застопорил. В общем, неразбериха...


 
Anatoly Podgoretsky ©   (2011-12-15 15:55) [29]


> И. Павел ©   (15.12.11 15:50) [25]

Дураки неистрибимы, это про твоих администраторов. Убить основной инструмент отладки.


 
Anatoly Podgoretsky ©   (2011-12-15 15:55) [30]

> OW  (15.12.2011 15:44:24)  [24]

Откатится транзакция


 
stas ©   (2011-12-15 15:59) [31]

Ega23 ©   (15.12.11 15:30) [21]

> теперь создаем 5 экземпляров того же потока, запускаем..

И?

Будет валится с разными ошибками. Может быть повезет пару раз...


 
stas ©   (2011-12-15 16:01) [32]

Например:

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EOleException with message "Операция не допускается, если объект открыт". Process stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------


 
Anatoly Podgoretsky ©   (2011-12-15 16:03) [33]

> stas  (15.12.2011 15:59:31)  [31]

С чего бы, у меня 15 потоков напряженно трудятся и ничего не валится. Есть
другие ошибки, но не эти


 
Ega23 ©   (2011-12-15 16:05) [34]


> Да и почитайте эту ветку, с этого же сайта


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


 
DiamondShark ©   (2011-12-15 16:05) [35]


> Ega23 ©   (15.12.11 13:35) [5]
> > 4. Connection лучше создать в том же потоке из которого
> > вы к нему обращаетесь как и command
> Докажи.

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

1. Будет маршалинг
2. Будет сериализация вызовов
3. Будет новая ветка на ДМ: "Почему у меня всё работает в обычном приложении, но всё зависает в сервисе?".


 
Ega23 ©   (2011-12-15 16:07) [36]


> Будет валится с разными ошибками. Может быть повезет пару раз...


Научи дурака Б-гу молиться - он и лоб себе разобьёт.


 
stas ©   (2011-12-15 16:11) [37]

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

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

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


 
Anatoly Podgoretsky ©   (2011-12-15 16:13) [38]

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

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


 
Ega23 ©   (2011-12-15 16:13) [39]


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


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


 
Ega23 ©   (2011-12-15 16:15) [40]


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


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


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

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

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

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


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

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

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


 
stas ©   (2011-12-15 16:23) [43]

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


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


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


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


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


Не только.


 
OW ©   (2011-12-15 16:29) [46]

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

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


 
stas ©   (2011-12-15 16:33) [47]

OW ©   (15.12.11 16:29) [46]

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


 
DiamondShark ©   (2011-12-15 16:37) [48]


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

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

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

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

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


 
Anatoly Podgoretsky ©   (2011-12-15 16:38) [49]

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

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


 
OW ©   (2011-12-15 16:41) [50]

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


 
DiamondShark ©   (2011-12-15 16:42) [51]


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

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


 
stas ©   (2011-12-15 16:44) [52]

OW ©   (15.12.11 16:41) [50]

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


 
OW ©   (2011-12-15 16:47) [53]


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

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


 
OW ©   (2011-12-15 16:47) [54]


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


?


 
Ega23 ©   (2011-12-15 16:51) [55]


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


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


 
DiamondShark ©   (2011-12-15 19:50) [56]


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

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



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

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

Наверх





Память: 0.6 MB
Время: 0.005 c
2-1324028884
Alatiel
2011-12-16 13:48
2012.04.08
помогите пожалуйста решить задачку по delphi


2-1324135784
igorium
2011-12-17 19:29
2012.04.08
TabControl и 64-битная Windows


15-1323376220
Юрий
2011-12-09 00:30
2012.04.08
С днем рождения ! 9 декабря 2011 пятница


6-1254688951
xarfan
2009-10-05 00:42
2012.04.08
Идентификация пользователей при работе с Сокетами (Delphi)


15-1323353360
Artem
2011-12-08 18:09
2012.04.08
Строки в паскале





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