Странное поведение ADO, генерирующее нежелательные NO_BROWSETABLE / установка fmtonly запросов в VB6
Я борюсь с некоторыми нежелательными запросами метаданных, автоматически генерируемыми ADO. Поведение началось после замены поставщика MSDASQL по умолчанию на SQLOLEDB. Я также попробовал SQLOLEDB, и поведение, кажется, то же самое.
Воспроизведение проблемы из среды IDE оказалось трудным, потому что, кажется, это происходит случайным образом. Еще более обнадеживающим является то, что эти запросы, по-видимому, запрашивают метаданные для ранее открытых (а затем закрытых) наборов записей.
1 ответ
Я обнаружил странное поведение, связанное с нежелательными запросами NO_BROWSETABLE / fmtonly / 1=2 с использованием ADO 2.8 в VB6 SP6 на компьютере с XP.
Следующий код будет воспроизводить поведение.
Private Sub Form_Load()
Dim oConn As ADODB.Connection
Set oConn = New ADODB.Connection
'oConn.Open "DRIVER=SQL Server;SERVER=***;UID=***;password=***;APP=***"
'oConn.Open "Provider=SQLOLEDB;SERVER=***;UID=***;password=***;APP=***"
'oConn.Open "Provider=SQLNCLI10;Server=***;UID=***;PWD=***;APP=***"
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
' Execute the first query
rst.Open "select 1", oConn
rst.Close
' Execute the second query without specifying a connection
rst.Open "select 2"
End Sub
Я протестировал приведенный выше код с использованием трех разных провайдеров. Вот результаты SQL Server Profiler.
Поставщик 1 (MSDASQL)
select 1
go
select 2
go
Поставщик 2 (SQLOLEDB)
select 1
go
-- This comes after executing the second query. Notice the query between FMTONLY ON/OFF is the FIRST query.
SET NO_BROWSETABLE ON
go
SET FMTONLY ON select 1 SET FMTONLY OFF
go
SET NO_BROWSETABLE OFF
go
select 2
go
Поставщик 3 (SQLNCLI10)
select 1
go
-- This comes after executing the second query. The behavior is the same as for SQLOLEDB, except that 'where 1=2' is appended to the query.
SET NO_BROWSETABLE ON
go
set fmtonly on select 1 where 1=2 set fmtonly off
go
SET NO_BROWSETABLE OFF
go
select 2
go
Заключение:
Если вы не укажете соединение во втором rst.Open, ADO запросит у сервера метаданные, касающиеся ПРЕДЫДУЩЕГО запроса, прежде чем продолжить.
rst.Open "select 2", oConn
Указание oConn, как указано выше, исключит запрос метаданных, а SQL Server Profiler выдаст одинаковые события для всех трех поставщиков.