Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Sesi Oracle yang tidak dapat dibunuh menunggu pesan SQL*Net dari acara klien

Ini tampaknya menjadi bug di Oracle ketika CLOB tipe data digunakan sebagai nilai yang diteruskan ke MERGE pernyataan ON ayat. Asumsikan database ini:

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

Reproduksi menggunakan nilai sebaris

Sekarang, jalankan pernyataan berikut di setiap klien Oracle, termasuk SQL*Plus, SQL Developer atau dari JDBC, yang membantu mereproduksi masalah dengan sangat mudah (Saya menggunakan 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);

Contohnya konyol, dan CLOB terikat di sini oleh "kecelakaan". Meskipun demikian, pernyataan seperti itu seharusnya tidak membuat sesi zombie di Oracle, tetapi ada di sana. Saya menjalankan pernyataan di atas tiga kali di SQL*Plus dan kemudian menjalankan ini...

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%';

... Saya mendapatkan:

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     

Perhatikan perbedaan peristiwa yang dilaporkan ("pembacaan berurutan file db" ) dari acara asli ("SQL*Net message from client" ), yang menggunakan variabel bind

Reproduksi menggunakan nilai ikatan

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);

Pernyataan di atas yang dijalankan di SQL*Plus juga menghasilkan bug:

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

Tidak ada reproduksi di PL/SQL

Menariknya, bug tersebut dihindari dalam pernyataan PL/SQL berikut:

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;
/

Saya mendapatkan:

          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

Sepertinya mesin PL/SQL menyelamatkan klien dari bug mesin SQL ini.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menentukan bahasa (Inggris, Cina ...) dari string yang diberikan di Oracle?

  2. Pemicu SQL untuk Tampilan

  3. Pemicu PL/SQL untuk memperbarui tabel lain dari INSERT di satu tabel

  4. Perl DBI - jalankan SQL Script dengan banyak pernyataan

  5. RESULT_CACHE kosong RESULT_ON