2013-07-31 26 views
5

Następująca kwerenda działa efektywnie, gdy uruchamiane bezpośrednio przeciwko Oracle 11 stosując Ropucha (z natywnych sterowników Oracle)SQL Server OPENQUERY() zachowuje się inaczej wtedy bezpośredni zapytanie z TOAD

select ... from ... where ... 
and srvg_ocd in (
    select ocd 
    from rptofc 
    where eff_endt = to_date('12/31/9999','mm/dd/yyyy') 
    and rgn_nm = 'Boston' 
) ... 
; 

dokładnie w tym samym zapytaniu „nigdy” powraca jeśli przeszedł z SQL Server 2008 do tej samej bazy danych Oracle przez openquery(). SQL Server ma łącze do bazy danych Oracle przy użyciu sterownika OLE DB dostawcy Oracle.

select * from openquery(servername, ' 
    select ... from ... where ... 
    and srvg_ocd in (
    select ocd 
    from rptofc 
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'') 
     and rgn_nm = ''Boston'' 
) ... 
'); 

Zapytanie nie powraca w rozsądnym czasie, a użytkownik zabija zapytanie. Nie wiem, czy w końcu wróci z poprawnym wynikiem.

Ten wynik, w którym zapytanie bezpośrednie TOAD działa sprawnie, a wersja openquery() "nigdy" nie jest zwracana, jest powtarzalna.

Mała modyfikacja openquery() daje prawidłowy efektywny wynik: Zmień eff_endt na trunc(eff_endt).

To dobrze i dobrze, ale nie wydaje się, żeby zmiana była konieczna.

openquery() ma zostać przekazany, więc jak może istnieć różnica między zachowaniem TOAD i openquery()?

Dbamy o to, ponieważ często opracowujemy złożone zapytania za pomocą TOAD bezpośrednio uzyskującego dostęp do Oracle. Po uzyskaniu funkcjonalności i optymalizacji zapytania, konwertujemy ją na ciąg znaków openquery() do użycia w aplikacji serwera SQL. Niezwykle obciążające jest to, że zapytanie nagle kończy się niepowodzeniem z openquery(), gdy wiemy, że działało jako bezpośrednie zapytanie. Następnie musimy szukać obejścia przez próbę i błąd.

Chciałbym zobaczyć pliki śledzenia Oracle dla dwóch scenariuszy, ale serwer Oracle znajduje się w innej organizacji, a my nie otrzymujemy współpracy z Oracle DBA.

Czy ktoś wie o jakimkolwiek kierowcy, TOAD, czy ??? problemy, które mogłyby wyjaśnić rozbieżności? Czy istnieje sposób, aby wyeliminować problem tak, że obie metody zawsze dają taki sam wynik?

Odpowiedz

1

Wiem, że pytałeś o to jakiś czas temu, ale właśnie natknąłem się na twoje pytanie.

Zgadzam się, powinny być takie same. Oczywiście jest różnica. Musimy dowiedzieć się, gdzie jest różnica.

myślę głośno jak wpisuję ...

Co się stanie, jeśli podasz tylko kilka kolumn zamiast select * from OPENQUERY?

Ile wierszy ma zostać zwróconych?

Co się stanie, jeśli w wyroczni zostanie wybrana ograniczona liczba zwróconych wierszy?

Jak szybko upłynął limit czasu?

Czy TOAD i SS znajdują się na tym samym komputerze? Czy przenosisz się do SS i prowadzisz od tego ropuchę?

Czy używają tych samych sterowników? w tym bit? (32/64) wersja?

Czy używają tego samego konta na wyroczni?

Interesujące jest to, że korzystanie z trunc() ma znaczenie. Zakładam, że [eff_endt] jest jednym z zwróconych pól?

Zastanawiam się, czy SS przywraca wszystkie wiersze, ale dławi się z powodu konwersji daty. Typ daty w oracle może wymagać przekonwertowania na typ daty ss, zanim ss go wyświetli.

Co się stanie, jeśli wstawisz wiersze z otwartej aplikacji do tabeli, w której pole daty jest po prostu (n)varchar. Myślę, że ss może po prostu zrzucić datę powrotu z oracle do tego pola tekstowego bez próby konwersji.

coś takiego:

insert into mytable(f1,f2,f3,datetimeX) 
select f1,f2,f3,datetimeX from openquery(servername, ' 
    select f1,f2,f3,datetimeX from ... where ... 
    and srvg_ocd in (
    select ocd 
    from rptofc 
    where eff_endt = to_date(''12/31/9999'',''mm/dd/yyyy'') 
     and rgn_nm = ''Boston'' 
) ... 
'); 

Co jeśli ropucha lub ss jest zmodyfikowanie instrukcję zapytania przed wysłaniem go do wyroczni. Możesz odpalić wireshark i zobaczyć, co ropucha i ss rzeczywiście wysyłają.

Byłbym bardzo ciekawy, gdyby to rozwiązanie zostało rozwiązane. Łączę ss z oracle często i nie napotkam tego problemu.

+0

Dokonaliśmy śladu po stronie SS - prawidłowe zapytanie jest wysyłane, a nic nigdy nie wraca z Oracle. Różne konta Oracle, ale nie widzę, w jaki sposób może to wyjaśnić różnicę w przypadku dodania problemu "naprawiania" skracania. Zestaw wyników jest bardzo mały, bez dat ani znaczników czasowych. OpenQuery nie kończy się na czas - użytkownik zmęczy się czekaniem i przerwie. TOAD i SS są na różnych maszynach, z różnymi sterownikami. Podejrzewamy sterowniki, ale szukam konkretnych informacji o znanych problemach. Zobaczę, czy mamy dostęp do czegoś takiego jak wireshark. – dbenham

+0

Właśnie dowiedziałem się, że sniffery ruchu sieciowego są zabronione w naszym miejscu pracy, więc nie ma dla nas żadnego wireshark. Przesyłamy za dużo danych wrażliwych. – dbenham

+0

Wygląda na to, że nie szyfrują swoich poufnych danych. Cóż, to jest temat na inną dyskusję. Zobaczę, czy mogę odtworzyć twój problem tutaj na mojej stronie. – SQLburn

1

Oto podstawowe czynności, które można sprawdzić, aby sprawdzić, co robi baza danych po otrzymaniu zapytania. Najpierw sprawdź, czy plany wykonania są takie same w TOAD, jak w przypadku uruchamiania kwerendy przy użyciu openquery. Można zaplanować zapytania samodzielnie w TOAD przy użyciu:

explain plan set statement_id = 'openquery_test' for <your query here>; 

select * 
from table(dbms_xplan.display(statement_id => 'openquery_test'; 

wtedy ktoś zainicjować kwerendę za pomocą OPENQUERY() i kogoś z uprawnieniami do widoku V $ stoły do ​​uruchomienia:

select sql_id from v$session where username = '<user running the query>'; 

(Jeśli istnieje więcej niż jednego połączenia z tego samego użytkownika, będziesz musiał znaleźć dodatkowy atrybut do odizolowania wiersz reprezentujący sesję z uruchomieniem kwerendy.)

select * 
from table(dbms_xplan.display_cursor('<value from query above')); 

Jeśli te wyglądają tak samo, a następnie Przejdę do sprawdzania bazy danych i zobaczę, na czym to polega.

select se.username 
    , sw.event 
    , sw.p1text 
    , sw.p2text 
    , sw.p3text 
    , sw.wait_time_micro/1000000 as seconds_in_wait 
    , sw.state 
    , sw.time_since_last_wait_micro/1000000 as seconds_since_last_wait 
    from v$session se 
     inner join 
     v$session_wait sw 
      on se.sid = sw.sid 
where se.username = '<user running the query>' 

;

(ponownie, jeśli istnieje więcej niż jedna sesja o tej samej nazwie, musisz inny atrybut zredukować go do tego, który Cię interesuje.)

Jeśli plany są różne, wtedy musisz dowiedzieć się, dlaczego lub jeśli są takie same, sprawdź, na co czeka (np. komunikat SQL * Net do klienta?) i dlaczego.

0

Zauważyłem różnicę przy użyciu OLEDB przez MS Access (2013) łączącego się z tabelami Oracle 11g, 102, &, ponieważ nie zawsze poprawnie rozpoznały indeksy lub klucze podstawowe w tabelach Oracle. To samo zapytanie za pośrednictwem bazy danych MS Access 2000 (przy użyciu odbc) działało poprawnie/nie miało problemu z kluczami indeksów &. Jedynym sposobem na naprawienie wersji OLEDB było uwzględnienie wszystkich kluczowych pól w SELECT - co nie było satysfakcjonującą odpowiedzią, ale to wszystko, co mogłem znaleźć. Może to być również opcja próbowania przez SSMS/OpenQuery (...).

Poza tym ... można spróbować alternatywy dla OPENQUERY, takie jak:

  • nazwy 4-częściowy: SELECT ... FROM Server..Schema.Table
  • Wykonanie AT: exec ("wybierz ...") na połączonym serwerze

Ale dlaczego dostawca OLEDB działa inaczej niż macierzysty dostawca Oracle - dostawcy nie są identyczni, a natywny dostawca będzie bardziej skłonny do przejścia na drugą stronę Wyjątki od Oraclea byłyby bardziej typowe dla dostawcy OLEDB.