Гость
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / DISTINCT в ADODB и в Management Studio / 7 сообщений из 7, страница 1 из 1
31.08.2019, 17:29
    #39855989
trigubovichaa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT в ADODB и в Management Studio
Помогите разобраться. Ситуация:
Скрипт на 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
01.09.2019, 10:47
    #39856069
trigubovichaa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT в ADODB и в Management Studio
Может кому пригодится, ибо вроде как разобрался:

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

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

я думаю ошибка у вас в коде
...
Рейтинг: 0 / 0
05.09.2019, 21:28
    #39858145
trigubovichaa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT в ADODB и в Management Studio
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
06.09.2019, 08:26
    #39858245
HandKot
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT в ADODB и в Management Studio
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
07.09.2019, 00:22
    #39858670
trigubovichaa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT в ADODB и в Management Studio
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
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / DISTINCT в ADODB и в Management Studio / 7 сообщений из 7, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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