Событие TADOConnection.OnExecuteComplete / OnWillExecute не вызывается с помощью TADOTable

Я пытаюсь отследить команду SQL. Я прочитал этот пост: Как я могу отслеживать команды SQL, отправляемые через мое соединение ADO?

Он работает для выбора, но не для удаления/вставки/обновления...

Конфигурация: TADOConnection (MS SQL Server), TADOTable, TDatasource, TDBGrid с TDBNavigator.

Таким образом, я могу проследить SELECT, которое происходит, когда таблица открыта, но ничего не происходит, когда я использую DBNavigator для UPDATE, INSERT или DELETE записей.

Когда я использую TADOCommand для удаления записи, это тоже работает. Кажется, это не работает только тогда, когда я использую DBNavigator, так что, может быть, подсказка, но я ничего не нахожу об этом.

заранее спасибо


person user2244705    schedule 27.01.2016    source источник
comment
Обратите внимание, что я использую Delphi XE7.   -  person user2244705    schedule 27.01.2016
comment
Поместите это в текст вопроса (и вы также можете добавить соответствующий тег)   -  person Jan Doggen    schedule 27.01.2016
comment
Мне нужно отслеживать Sql программно, внутри приложения, а не с сервера Sql, потому что мне нужна информация, которой нет на сервере. Вот это ограничение...   -  person user2244705    schedule 27.01.2016
comment
@MartynA: Может, названия q достаточно?   -  person user2244705    schedule 27.01.2016
comment
Приложение использует DbGrid/DbNav для отображения, обновления, вставки и удаления записей. Чтобы отобразить записи, сделайте следующее: ADOC.ConnectionString := GetConnString(); TB_EMC2LAB.Active:=Истина; OnExecuteComplete работает. Я вижу команду SELECT в журнале. Затем, если я попытаюсь обновить запись, в форме я наберу текст, а затем нажму кнопку «Обновить». Ничего не произошло. Запись обновлена. Но нет журнала с «ОБНОВЛЕНИЕМ и т. д.».   -  person user2244705    schedule 27.01.2016
comment
@martynA, это очень просто, код не нужен. TADOTable загрузит внутренний объект набора записей ADO, запустив выбор при загрузке, а затем будет использовать объект набора записей для операторов CRUD, минуя TADOConnection.   -  person whosrdaddy    schedule 27.01.2016
comment
@whosrdaddy: Спасибо, это объясняет, почему события не срабатывают при использовании DBNav, но я все еще озадачен тем, что именно говорит OP, работает ...   -  person MartynA    schedule 27.01.2016
comment
@MartynA, это работает, когда вы заменяете TADOTable на TADOCommand, потому что TADOCommand всегда будет использовать ADOConnection вместо внутреннего набора записей.   -  person whosrdaddy    schedule 27.01.2016
comment
@whosrdaddy: Есть ли способ запустить событие? Я не могу понять, как DBNav обходит ADOConnection... Что это значит? ADOConnection — это единственный известный приложению способ взаимодействия с базой данных.   -  person user2244705    schedule 27.01.2016
comment
Кажется, что операции над набором записей не захвачены этими событиями.   -  person whosrdaddy    schedule 27.01.2016
comment
Так ? Абсолютно нет возможности зарегистрировать обновление?   -  person user2244705    schedule 27.01.2016
comment
как DBNav обходит ADOConnection. Это не dBNav, который делает обход. Когда вы открываете AdoTable, он создает экземпляр объекта набора записей ADO (на уровне MDAC), который имеет собственный доступ к объекту подключения ADO (также на уровне MDAC), который подключается к серверу, как это делает AdoConnection в вашем приложении. Таким образом, это набор записей, который обходит AdoConnection, а не DBNav.   -  person MartynA    schedule 27.01.2016
comment
@MartynA: Спасибо за точность.   -  person user2244705    schedule 27.01.2016


Ответы (1)


Надеюсь, кто-нибудь сможет указать вам направление уже существующей библиотеки, которая будет вести журнал за вас. В частности, если FireDAC является опцией, вы можете взглянуть на то, что здесь написано:

http://docwiki.embarcadero.com/RADStudio/XE8/en/Database_Alerts_%28FireDAC%29

Конечно, преобразование вашего приложения с использования Ado в FireDAC может быть не для вас вариантом, но в зависимости от того, насколько велики ваши потребности, вы могли бы извлечь специфический для Sql-Server метод оповещения о событиях, который использует FireDAC, в приложение Ado. Я кратко рассмотрел это некоторое время назад, и казалось, что это будет довольно просто.

До FireDAC я внедрил решение на стороне сервера, которое перехватывало вставки, обновления и удаления. Мне пришлось сделать это около 10 лет назад (для Sql Server 2000), и настроить его было довольно сложно.

В общих чертах это работало так:

Sql Server поддерживает то, что MS раньше называла «расширенными хранимыми процедурами», которые реализованы в пользовательских библиотеках DLL (в наши дни MS может называть их другим именем или даже прекратила их поддержку). Существуют библиотеки Delphi, которые предоставляют оболочку, позволяющую писать их в Delphi. Конечно, в наши дни, если ваш Sql-сервер 64-разрядный, вам необходимо создать 64-разрядную DLL.

Вы пишете расширенные хранимые процедуры для регистрации изменений любым удобным для вас способом, а затем пишете настраиваемые триггеры в базе данных для вставок, обновлений и удалений, которые передают данные строк, участвующих в ваших XSP.

По счастливой случайности моя потребность в этом отпала, как только я завершал проект, прежде чем я начал стресс-тестирование и профилирование производительности, но это действительно сработало.

Конечно, не в каждой среде вам будет разрешено/возможность устанавливать s/ware и запускать код на сервере Sql.

Для интереса вы также можете взглянуть на https://msdn.microsoft.com/en-us/library/ms162565.aspx, который предоставляет объект SMO для отслеживания активности Sql Server, хотя на данный момент он только 32-разрядный.

Ради развлечения я мог бы попробовать реализовать обработчик событий для объекта набора записей, лежащего в основе TAdoTable/TAdoQuery, который мог бы уловить изменения, которые вам нужны, но не задерживайте дыхание...

И, конечно же, если вас интересует только ведение журнала на стороне клиента, один из способов сделать это — написать обработчики событий AfterEdit, AfterInsert и AfterDelete вашего набора данных. Конечно, это не гарантирует, что изменения действительно будут применены на сервере, но может обеспечить точную запись активности пользователя, если этого достаточно для ваших нужд.

person MartynA    schedule 27.01.2016
comment
Хорошо, большое спасибо за ваши знания и ваше время. FireDac мне не подходит, и у меня нет доступа к серверу. Итак... действительно, я пишу такой код: AfterEdit, AfterInsert, BeforeDelete и так далее на уровне набора данных. И то, что можно было бы элегантно написать за два часа с помощью ADO, теперь займет два дня и столько-то строк грязного кода. Но нет выбора. Я буду работать этой ночью :-(. Однако я считаю, что в Delphi не хватает возможности использовать ADO ни при каких обстоятельствах, DataSet или нет. С уважением. - person user2244705; 27.01.2016