2017-08-21 49 views
6

ऑरेकल:क्यों ओरेकल अद्यतन कर सकते हैं पी = पी + 1, लेकिन MySQL अद्यतन नहीं कर सकते सेट पी = पी + 1

create table t7(c1 number primary key,c2 number); 
insert into t7 values (1,3); 
insert into t7 values (2,4); 
commit; 
update t7 set c1=c1+1; 
commit ; 
select * from t7; 

MySQL:

create table t7(c1 int primary key,c2 int); 
insert into t7 values (1,3); 
insert into t7 values (2,4); 
select * from t7; 
update t7 set c1=c1+1; 
ERROR 1062 (23000): Duplicate entry '2' for key 'PRIMARY' 

MySQL क्यों कहते है

update set pk=pk+1 :Duplicate entry '2' for key 'PRIMARY',

जबकि ओरेकल यह update set pk=pk+1 कर सकता है?

+0

दिलचस्प। मुझे लगता है कि यह अद्यतन बयान चलाते समय पंक्तियों को कैसे लाया जाता है इस पर निर्भर करता है। यदि पहली पंक्ति से पहले दूसरी पंक्ति अपडेट की जाती है तो आपको यह तब तक नहीं मिलेगा जब तक कि 2 को पहले से ही 3 में अपडेट किया गया हो। मैं शर्त लगाता हूं कि अगर आप कुछ हजार पंक्तियों पर ओरेकल चीज का प्रयास करते हैं, तो आपको भी इसी तरह की त्रुटि मिल जाएगी। – Utsav

+0

@ नोब प्राथमिक कुंजी संयम केवल अस्थायी रूप से उल्लंघन कर रहे हैं। अद्यतन पूरा होने के बाद सभी मान एक बार फिर अनूठे होते हैं, यही कारण है कि रिवर्स ऑर्डर (सबसे बड़ा से शुरू) में अपडेट करना ठीक है, यहां तक ​​कि mysql में भी। – user3141593

+0

@Utsav हिंडसाइट में मैं स्पष्ट रूप से ऑरैकल में बदलाव करने के लिए दोषी ठहराऊंगा। यदि अद्यतन "लेनदेन" में होता है और बाधाओं को केवल तभी चेक किया जाता है जब आप परिवर्तन करने का प्रयास करते हैं तो यह अद्यतन के दौरान ओवरलैपिंग कुंजी को नोटिस नहीं करेगा। यह निश्चित रूप से जंगली अटकलें है क्योंकि मेरे पास 0 ज्ञान या ऑरैकल के साथ अनुभव है। – user3141593

उत्तर

2

ऐसा लगता है ओरेकल या तो निष्पादन आदेश के बारे में होशियार है, या केवल सभी पंक्तियों को अद्यतन लागू करने के बाद की कमी की जांच करता है। किसी भी तरह, mysql उदाहरण अद्यतन पर ऑर्डर निर्दिष्ट करके तय किया जा सकता है।

create table t7(c1 int primary key,c2 int); 
insert into t7 values (1,3); 
insert into t7 values (2,4); 
select * from t7; 
update t7 set c1=c1+1 order by c1 desc; 

http://sqlfiddle.com/#!9/8611f4/1

(2,3) के लिए पहली पंक्ति को अद्यतन करने की कोशिश कर रहा के बाद से (2,4) एक नकली चाबी है देखना अभी भी पुराने मान होते हैं। इस व्यवहार के लिए कामकाज आदेश को उलटना और सबसे बड़ी अनुक्रमणिका के साथ शुरू करना है, (2,4) -> (3,4) और फिर (1,3) -> (2,3), और टक्कर से पूरी तरह से परहेज करना ।

+2

तकनीकी रूप से, "तार्किक ठीक" एक सेट करने के लिए आवेदन के रूप में आपरेशन के इलाज के लिए है (जो है: तार्किक अद्यतन एक साथ सभी पंक्तियों के लिए लागू किया जाता है)। मुझे नहीं पता ** कैसे ** ओरेकल लागू करता है (क्योंकि, वास्तव में, वास्तविक जीवन पंक्तियों में एक समय में एक अद्यतन किया जाना चाहिए); सबसे अधिक संभावना है कि यह सभी पंक्तियों को अद्यतन करता है, जो भी क्रम में, और केवल तभी जांचता है कि सभी बाधाएं अभी भी संतुष्ट हैं या नहीं।लेकिन तार्किक रूप से - हमें इसके बारे में ** ** कैसे सोचना चाहिए - एक सेट ऑपरेशन के रूप में है। – mathguy

+0

@mathguy अंतर्दृष्टि के लिए धन्यवाद, आप बिल्कुल सही हैं। मुझे लगता है कि मैं एक "टूटा हुआ" कार्यान्वयन बनाने के लिए दोषी हूं और फिर मेरे सिर में "इसके चारों ओर काम कर रहा हूं", एक डीबी क्या होना चाहिए चिपके रहने के बजाय। इस सवाल पर भी मेरी अटकलें कार्यान्वयन के विवरण तक ही सीमित थीं कि सिस्टम को व्यवहार करने का लक्ष्य कैसे होना चाहिए। – user3141593

1

संबंधपरक डेटाबेस में, वहाँ धारणात्मक सीमित अर्थ (बिल्कुल नहीं कहने के लिए नहीं) अपने प्राथमिक कुंजी अद्यतन करने के लिए है।

ओरेकल इस लागू किया, जबकि MySQL नहीं किया। आपने इसे खोज लिया

तुम सच में तुम क्या विचार कर रहे हैं चाहते हैं, समाधान नया रिकार्ड डालने के लिए है, तो हटाने होंगे।

पूरे मेज पर करते हैं, बेहतर एक अस्थायी तालिका बनाने के लिए। यहां बताया गया है कि यह कैसा दिखता है:

create table t7_tmp(c1 int primary key,c2 int); 
insert into t7_tmp (select c1+1,c2 from t7); 
delete t7; 
insert into t7 (select c1,c2 from t7_tmp); 
drop table t7_tmp; 
संबंधित मुद्दे