यह Oracle में एक बग लगता है जब CLOB
डेटा प्रकारों का उपयोग उन मानों के रूप में किया जाता है जो MERGE
. को पास किए जाते हैं स्टेटमेंट का ON
खंड। इस डेटाबेस को मान लें:
CREATE TABLE t (
v INT,
s VARCHAR2(400 CHAR)
);
इनलाइन मानों का उपयोग करके पुनरुत्पादन
अब, SQL*Plus, SQL Developer या JDBC सहित किसी भी Oracle क्लाइंट में निम्न कथन चलाएँ, जो समस्या को बहुत आसानी से पुन:उत्पन्न करने में मदद करता है (मैं 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);
उदाहरण मूर्खतापूर्ण है, और CLOB
यहाँ "दुर्घटना" से बंधा था। फिर भी, इस तरह के एक बयान को Oracle में एक ज़ोंबी सत्र नहीं बनाना चाहिए, लेकिन यह वहाँ है। मैं उपरोक्त कथन को SQL*Plus में तीन बार चला रहा हूँ और फिर इसे चला रहा हूँ...
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%';
... मुझे मिलता है:
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
ध्यान दें कि रिपोर्ट की गई घटना कैसे भिन्न होती है ("db फ़ाइल अनुक्रमिक पठन" ) मूल घटना से ("एसक्यूएल*क्लाइंट से नेट संदेश" ), जो बाइंड वैरिएबल का उपयोग कर रहा था
बाइंड मानों का उपयोग करके पुनरुत्पादन
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);
उपरोक्त कथन SQL*प्लस में चलता है और यह भी बग उत्पन्न करता है:
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
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;
/
मुझे मिल रहा है:
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
ऐसा लगता है कि PL/SQL इंजन क्लाइंट को इस SQL इंजन बग से बचाता है।