Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Niemożliwa do zabicia sesja Oracle oczekująca na wiadomość SQL*Net ze zdarzenia klienta

Wygląda na to, że jest to błąd w Oracle, gdy CLOB typy danych są używane jako wartości, które są przekazywane do MERGE ON instrukcji klauzula. Załóżmy, że ta baza danych:

CREATE TABLE t (
  v INT, 
  s VARCHAR2(400 CHAR)
);

Reprodukcja przy użyciu wartości wbudowanych

Teraz uruchom następującą instrukcję w dowolnym kliencie Oracle, w tym SQL*Plus, SQL Developer lub z JDBC, co bardzo ułatwia odtworzenie problemu (używam Oracle 11g XE 11.2.0.2.0):

MERGE INTO t                      
USING (
  SELECT 
    1 v, 
    CAST('abc' AS CLOB) s 
  FROM DUAL
) s 
ON (t.s = s.s) -- Using a CLOB here causes the bug.
WHEN MATCHED THEN UPDATE SET
  t.v = s.v        
WHEN NOT MATCHED THEN INSERT (v, s) 
VALUES (s.v, s.s);

Przykład jest głupi, a CLOB był tu związany „wypadkiem”. Niemniej jednak takie stwierdzenie nie powinno tworzyć sesji zombie w Oracle, ale jest. Uruchamiam powyższą instrukcję trzy razy w SQL*Plus, a następnie uruchamiam to...

SELECT 
  s.sid,
  s.serial#,
  s.sql_id,
  s.event,
  s.blocking_session,
  q.sql_text
FROM v$session s
JOIN v$sql q
ON s.sql_id = q.sql_id
WHERE s.username = 'TEST'
AND UPPER(TRIM(q.sql_text)) LIKE 'MERGE%';

... otrzymuję:

sid serial# sql_id          event                       blocking_session
9   3       82a2k4sqzy1jq   cursor: pin S wait on X     92
49  89      82a2k4sqzy1jq   cursor: pin S wait on X     92
92  13      82a2k4sqzy1jq   db file sequential read     

Zwróć uwagę, jak różni się raportowane zdarzenie ("odczyt sekwencyjny pliku db" ) z oryginalnego zdarzenia ("Wiadomość SQL*Net od klienta" ), który używał zmiennych bind

Powielanie przy użyciu wartości wiązania

var v_s varchar2(50)
exec :v_s := 'abc'

MERGE INTO t                      
USING (
  SELECT 
    1 v, 
    CAST(:v_s AS CLOB) s 
  FROM DUAL
) s 
ON (t.s = s.s) -- Using a CLOB here causes the bug.
WHEN MATCHED THEN UPDATE SET
  t.v = s.v        
WHEN NOT MATCHED THEN INSERT (v, s) 
VALUES (s.v, s.s);

Powyższa instrukcja uruchomiona w SQL*Plus również powoduje błąd:

sid serial# sql_id          event                           blocking_session
8   1       4w9zuxrumumgj   SQL*Net message from client     
90  7       4w9zuxrumumgj   cursor: pin S wait on X         8
94  21      4w9zuxrumumgj   cursor: pin S wait on X         8

Brak reprodukcji w PL/SQL

Co ciekawe, błędu omija następująca instrukcja PL/SQL:

DECLARE
  v_s CLOB := 'abc';
BEGIN
  MERGE INTO t                      
  USING (
    SELECT 
      1 v, 
      CAST(v_s AS CLOB) s 
    FROM DUAL
  ) s 
  ON (t.s = s.s) -- Using a CLOB here causes the bug.
  WHEN MATCHED THEN UPDATE SET
    t.v = s.v        
  WHEN NOT MATCHED THEN INSERT (v, s) 
  VALUES (s.v, s.s);
END;
/

Otrzymuję:

          CAST(v_s AS CLOB) s
          *
ERROR at line 8:
ORA-06550: line 8, column 11:
PL/SQL: ORA-00932: inconsistent datatypes: expected - got CLOB
ORA-06550: line 4, column 7:
PL/SQL: SQL Statement ignored

Wygląda na to, że silnik PL/SQL chroni klientów przed tym błędem silnika SQL.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wprowadzenie do Oracle Mobile Cloud Service

  2. Radzenie sobie z dużymi danymi JSON zwracanymi przez Web API

  3. Wysyłanie zapytań do bazy danych Oracle za pomocą nazw tabel dynamicznych

  4. Zwrócić nazwy kolumn Oracle w formacie table.column?

  5. Oracle Regexp do zastąpienia \n,\r i \t spacją