Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Phiên Oracle không thể thực hiện được đang chờ trên SQL * Thông báo mạng từ sự kiện máy khách

Đây dường như là một lỗi trong Oracle khi CLOB kiểu dữ liệu được sử dụng làm giá trị được chuyển đến MERGE của câu lệnh ON mệnh đề. Giả sử cơ sở dữ liệu này:

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

Sao chép bằng các giá trị nội dòng

Bây giờ, hãy chạy câu lệnh sau trong bất kỳ máy khách Oracle nào, bao gồm SQL * Plus, SQL Developer hoặc từ JDBC, giúp tái tạo sự cố rất dễ dàng (Tôi đang sử dụng 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);

Ví dụ thật ngớ ngẩn và CLOB đã bị ràng buộc ở đây bởi "tình cờ". Tuy nhiên, một câu lệnh như vậy không nên tạo ra một phiên thây ma trong Oracle, nhưng nó ở đó. Tôi đang chạy câu lệnh trên ba lần trong SQL * Plus và sau đó chạy câu lệnh này ...

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

... Tôi nhận được:

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     

Lưu ý sự kiện được báo cáo khác nhau như thế nào ( "đọc tuần tự tệp db" ) từ sự kiện ban đầu ( "Thông báo SQL * Net từ máy khách" ), đang sử dụng các biến liên kết

Sao chép sử dụng các giá trị ràng buộc

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

Câu lệnh trên chạy trong SQL * Plus cũng tạo ra lỗi:

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

Không sao chép trong PL / SQL

Thật thú vị, lỗi được tránh trong câu lệnh PL / SQL sau:

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

Tôi nhận được:

          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

Có vẻ như công cụ PL / SQL bảo vệ máy khách khỏi lỗi công cụ SQL này.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kiểm tra xem một mục không tồn tại trong bảng khác hay không

  2. Làm thế nào để mã hóa mật khẩu trong Oracle?

  3. không thể lấy tham số từ thủ tục được lưu trữ bằng php

  4. Đồng bộ hóa thủ tục PL / SQL. Làm thế nào để đảm bảo thực hiện thủ tục một lần duy nhất?

  5. Oracle-XMLTYPE:Cách cập nhật giá trị