powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / DISTINCT в ADODB и в Management Studio
7 сообщений из 7, страница 1 из 1
DISTINCT в ADODB и в Management Studio
    #39855989
trigubovichaa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Помогите разобраться. Ситуация:
Скрипт на VBS отправляет запрос Q к MS SQL Server 2008R2 посредством ADODB (Provider = "SQLOLEDB").
Q = "SELECT DISTINCT A FROM Table"
В результате исполнения ADODB.Recordset возвращается пустой.

Этот же запрос Q , исполненный в MS SQL Server Management Studio возвращает 51 строку.

Таблица содержит кириллицу и в наименовании столбцов и в полях.

Момент: если из Q убрать DISTINCT, ADODB.Recordset возвращается непустым .

Вопрос: почему реакция ADODB на ключевое слово DISTINCT кардинально отличается от реакции самого SQL Server?
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39856069
trigubovichaa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может кому пригодится, ибо вроде как разобрался:

Где-то вычитал на форумах, что ODBC-драйвера не умеют в DISTINCT запросы на стороне СУБД. Проблемы не только у меня с MS SQL Server, но у людей с Oracle. И да, к моему удивлению, оказалось, что запрос имеет свойство: выполняться на стороне клиента или выполняться на стороне СУБД. С выставленным свойством объекта Recordset .CursorLocation = adUseClient запрос вида "SELECT DISTINCT... " начал-таки возвращать строки. При этом время выполнения запроса раза в два-три выше аналогичного к таблице Excel.
Это печально, господа. ADO существует с 1996 года, ODBC еще дольше, но ср*ный DISTINCT запрос не может быть исполнен силами СУБД.
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39856167
Фотография HandKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
trigubovichaa, фигню говорите
У меня все возвращается корректно.
приведите скрипт, может Вы где-то что-0то не так сделали
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39856304
Фотография Focha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
trigubovichaaМожет кому пригодится, ибо вроде как разобрался:

Где-то вычитал на форумах, что ODBC-драйвера не умеют в DISTINCT запросы на стороне СУБД. Проблемы не только у меня с MS SQL Server, но у людей с Oracle. И да, к моему удивлению, оказалось, что запрос имеет свойство: выполняться на стороне клиента или выполняться на стороне СУБД. С выставленным свойством объекта Recordset .CursorLocation = adUseClient запрос вида "SELECT DISTINCT... " начал-таки возвращать строки. При этом время выполнения запроса раза в два-три выше аналогичного к таблице Excel.
Это печально, господа. ADO существует с 1996 года, ODBC еще дольше, но ср*ный DISTINCT запрос не может быть исполнен силами СУБД.

я думаю ошибка у вас в коде
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39858145
trigubovichaa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HandKottrigubovichaa, фигню говорите
У меня все возвращается корректно.
приведите скрипт, может Вы где-то что-0то не так сделали

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
'              Provider   SQLServer_PC   DB_Name     User Password
Param = Array("SQLOLEDB", "localhost", "KCSAO_ASRK", "EE", "EE")
TableName = "TST"
ColomnName = "PLC"
conn_str = "Provider=" & Param(0) & _
           ";Data Source=" & Param(1) & _
           ";Initial Catalog=" & Param(2) &_
           ";UID=" & Param(3) & _
           ";PWD=" & Param(4)
Set Conn = CreateObject("ADODB.Connection")
If Not Conn Is Nothing Then 
    With Conn
        If .State <> 0 Then .Close
        .Open conn_str
'        If .State = 1 Then MsgBox "Connection established"
    End With

    Set RS = CreateObject("ADODB.Recordset")
    If Not RS Is Nothing Then
        Q = "SELECT DISTINCT " & ColomnName & " FROM " & TableName
        With RS
                Set .ActiveConnection = Conn
                .LockType = 3 'adLockOptimistic
                .CursorLocation = 3 'adUseClient
                .CursorType = 1 'adOpenKeyset
                .Open Q, , , , 1 'adCmdText
                MsgBox "RS.CursorLocation = " & .CursorLocation & vbNewLine & "RS.RecordCount = " & .RecordCount
                If .State <> 0 Then .Close
                .CursorLocation = 2 'adUseServer
                .Open Q, , , , 1 'adCmdText
                MsgBox "RS.CursorLocation = " & .CursorLocation & vbNewLine & "RS.RecordCount = " & .RecordCount
                If .State <> 0 Then .Close
        End With
        If RS.State <> 0 Then RS.Close
    End If
    Conn.Close
    Set RS = Nothing
    Set Conn = Nothing
End If
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39858245
Фотография HandKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
trigubovichaa,
У Вас возвращается тип курсора forward-only cursor для серверного курсора, а этот тип курсора всегда возвращает -1 для кол-ва записей
автор The RecordCount property will return -1 for a forward-only cursor; the actual count for a static or keyset cursor; and either -1 or the actual count for a dynamic cursor, depending on the data source.
Это не означает, что
trigubovichaa В результате исполнения ADODB.Recordset возвращается пустой.
...
Это печально, господа. ADO существует с 1996 года, ODBC еще дольше, но ср*ный DISTINCT запрос не может быть исполнен силами СУБД
...
Рейтинг: 0 / 0
DISTINCT в ADODB и в Management Studio
    #39858670
trigubovichaa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HandKot, благодарю: теперь я знаю, что
авторIf a provider does not support the requested cursor type, it may return another cursor type. источник здесь .
В моем случае провайдер SQLOLEDB на стороне сервера при запросе, содержащем DISTINCT , заменил тип курсора с adOpenKeyset на adOpenForwardOnly . При таком курсоре .RecordCount = -1 и такая удобная GetFields не работает. Действительно, результат возвращается (УРА!), но его нужно вытаскивать построчно.
Тот же самый провайдер на стороне сервера при точно таком же запросе, но без ключевого слова DISTINCT , тип курсора не тронул ( ! ) и вернул целиком RecordSet со всеми плюшками. И это вызывает у меня, в силу скудных познаний в предмете, недоумение: "А чо мешает-то с дистинктом?!".

При всем вышеописанном имеем еще один момент, подливающий масла к моему пылающему пердаку:
провайдер Microsoft.Jet.OLEDB.4.0 на запросы с DISTINCT на стороне сервера может возвращать целый RecordSet. Какой при этом тип курсора использовался - для меня уже второстепенно.

Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
Function Connect()
'                  Provider   SQLServer_PC   DB_Name     User Password
    Param = Array("SQLOLEDB", "localhost", "KCSAO_ASRK", "EE", "EE")
    conn_str = "Provider=" & Param(0) & _
               ";Data Source=" & Param(1) & _
               ";Initial Catalog=" & Param(2) &_
               ";UID=" & Param(3) & _
               ";PWD=" & Param(4)
    Set Conn = CreateObject("ADODB.Connection")
    If Conn Is Nothing Then Exit Function
    With Conn
        If .State <> 0 Then .Close
        .Open conn_str
'        If .State = 1 Then MsgBox "Connection established"
    End With
    Set Connect = Conn
End Function

Sub GO(Conn, fDistinct)
    Set RS = CreateObject("ADODB.Recordset")
    If RS Is Nothing Then Exit Sub
    TableName = "TST"
    ColomnName = "PLC"
    If fDistinct Then
        Q = "SELECT DISTINCT " & ColomnName & " FROM " & TableName
    Else
        Q = "SELECT " & ColomnName & " FROM " & TableName
    End If
    With RS
        Set .ActiveConnection = Conn
        .LockType = 3 'adLockOptimistic
        .CursorLocation = 3 'adUseClient
        .CursorType = 1 'adOpenKeyset
        MsgBox "Q = " & Q & vbNewLine & _
               "Before .Open" & vbNewLine & _
               "RS.CursorType = " & .CursorType & vbNewLine & _
               "RS.CursorLocation = " & .CursorLocation,, _
               "Курсор на стороне клиента. До открытия RS"
        .Open Q, , , , 1 'adCmdText
        MsgBox "Q = " & Q & vbNewLine & _
               "After .Open" & vbNewLine & _
               "RS.CursorType = " & .CursorType & vbNewLine & _
               "RS.CursorLocation = " & .CursorLocation & vbNewLine & _
               "RS.RecordCount = " & .RecordCount,, _
               "Курсор на стороне клиента. После открытия RS"
        If .State <> 0 Then .Close

        .LockType = 3 'adLockOptimistic
        .CursorLocation = 2 'adUseServer
        .CursorType = 1 'adOpenKeyset
'        .CursorType = 3 'adOpenStatic
        MsgBox "Q = " & Q & vbNewLine & _
               "Before .Open" & vbNewLine & _
               "RS.CursorType = " & .CursorType & vbNewLine & _
               "RS.CursorLocation = " & .CursorLocation,, _
               "Курсор на стороне сервера. До открытия RS"
        .Open Q, , , , 1 'adCmdText
        MsgBox "Q = " & Q & vbNewLine & _
               "After .Open" & vbNewLine & _
               "RS.CursorType = " & .CursorType & vbNewLine & _
               "RS.CursorLocation = " & .CursorLocation & vbNewLine & _
               "RS.RecordCount = " & .RecordCount,, _
               "Курсор на стороне сервера. После открытия RS"
        If .State <> 0 Then .Close
    End With
    Conn.Close
    Set RS = Nothing
    Set Conn = Nothing
End Sub

GO Connect, True
GO Connect, False
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / DISTINCT в ADODB и в Management Studio
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]