इसे चलाने से पहले SQL अपडेट स्टेटमेंट का परीक्षण कैसे करें?


96

कुछ मामलों में, उत्पादन में एक अद्यतन कथन चलाने से दिन बच सकता है। हालाँकि एक बोर्क्ड अद्यतन प्रारंभिक समस्या से भी बदतर हो सकता है।

एक परीक्षण डेटाबेस का उपयोग करने से कम, यह बताने के लिए कि अपडेट स्टेटमेंट को चलाने से पहले क्या करना होगा विकल्प हैं?

जवाबों:


50

एक लेन-देन का उपयोग करने के अलावा जैसा कि इमाद ने कहा है (जो वैसे भी अनिवार्य होना चाहिए) आप एक पवित्रता जांच भी कर सकते हैं कि कौन सी पंक्तियां एक ही WHERE क्लॉज के रूप में UPDATE का उपयोग करके चल रही हैं।

तो अगर आप UPDATE है

UPDATE foo
  SET bar = 42
WHERE col1 = 1
  AND col2 = 'foobar';

निम्नलिखित आपको दिखाएंगे कि कौन सी पंक्तियों को अपडेट किया जाएगा:

SELECT *
FROM foo
WHERE col1 = 1
  AND col2 = 'foobar';

1
तब डेटा की जांच करने के लिए लेनदेन का उपयोग करना बेहतर होता है। यह मानते हुए कि वह परिणाम की जांच करना चाहता है, मैं यह कहता हूं कि उसका कथन 'SET बार = 42' की तुलना में अधिक जटिल है, इसलिए अपने सत्र के भीतर वह डेटा के परिणामी सेट का परीक्षण करने के लिए कई प्रश्न करने में सक्षम होगा ...
इमाद मुकद्दम

3
@ImadMoqaddem: मैं सहमत हूं और इसीलिए मैंने लिखा है " इसके अलावा एक लेन-देन का उपयोग करने के अलावा इमाद ने कहा "
a_horse_with_no_name

और अगर आपके पास FOREIGN KEY UPDATE CASCADEआपकी एसक्यूएल विफल है
ग्रीन

@ग्रीन: "फेल" से आपका क्या मतलब है?
a_horse_with_no_name

73

लेन-देन के बारे में क्या? उनके पास रोलबैक-फीचर है।

@see https://dev.mysql.com/doc/refman/5.0/en/commit.html

उदाहरण के लिए:

START TRANSACTION;
SELECT * FROM nicetable WHERE somthing=1;
UPDATE nicetable SET nicefield='VALUE' WHERE somthing=1;
SELECT * FROM nicetable WHERE somthing=1; #check

COMMIT;
# or if you want to reset changes 
ROLLBACK;

SELECT * FROM nicetable WHERE somthing=1; #should be the old value

नीचे @rickozoe से सवाल पर जवाब:

सामान्य तौर पर इन लाइनों को एक बार में निष्पादित नहीं किया जाएगा। PHP में आप ऐसा कुछ लिखेंगे (शायद थोड़ा सा क्लीनर, लेकिन त्वरित जवाब देना चाहते हैं ;-));

$MysqlConnection->query('START TRANSACTION;');
$erg = $MysqlConnection->query('UPDATE MyGuests SET lastname='Doe' WHERE id=2;');
if($erg)
    $MysqlConnection->query('COMMIT;');
else
    $MysqlConnection->query('ROLLBACK;');

एक अन्य तरीका MySQL वेरिएबल्स का उपयोग करना होगा (देखें https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l और https://stackoverflow.com/a/18499823/1416909 ):

# do some stuff that should be conditionally rollbacked later on

SET @v1 := UPDATE MyGuests SET lastname='Doe' WHERE id=2;
IF(v1 < 1) THEN
    ROLLBACK;
ELSE
    COMMIT;
END IF;

लेकिन मैं आपकी पसंदीदा प्रोग्रामिंग भाषा में उपलब्ध भाषा के रैपर का उपयोग करने का सुझाव दूंगा।


1
यह नेस्टेड लेनदेन के साथ अप्रत्याशित परिणाम होगा।
scones

क्या आप एक उदाहरण दे सकते हैं?
मार्सेल लैंग

@ जेसीएम और अन्य, आप यह कैसे जान सकते हैं कि क्या यह अपडेट स्टेटमेंट लाइन 3 पर सफल होता है ताकि आप कमिट और रोलबैक कर सकें?
रिको ज़ो

56

स्वतः पूर्ण बंद ...

माई एसक्यूएल

set autocommit=0;

यह वर्तमान सत्र के लिए ऑटोमीट को बंद कर देता है।

आप अपने बयान को निष्पादित करते हैं, देखें कि यह क्या बदल गया है, और फिर गलत होने पर रोलबैक करें या यदि आप उम्मीद करते हैं कि यह प्रतिबद्ध है!

संपादित करें: चुनिंदा क्वेरी चलाने के बजाय लेनदेन का उपयोग करने का लाभ यह है कि आप परिणामी सेट को आसानी से देख सकते हैं।


4
@ डायस्ट्रो: हर ​​समझदार डीबीएमएस लेनदेन का समर्थन करता है।
a_horse_with_no_name

7
बस लेनदेन को जल्दी से कमिट या रोलबैक करना याद रखें, या आप अन्य लेनदेन को अवरुद्ध करने का जोखिम उठाते हैं - और सबसे खराब स्थिति में आपके आवेदन को पीसने वाले पड़ाव तक लाना। क्वेरी को निष्पादित करने के लिए एक अच्छा विचार नहीं है, फिर दोपहर का भोजन है, फिर परिणाम देखने के लिए वापस आएं! :-)
गैरी मैकगिल

@GaryMcGill: लंबित लेन-देन (कम से कम आधुनिक DBMS में) केवल अन्य लेखन लेनदेन को अवरुद्ध करेगा ।
a_horse_with_no_name

5
@ डिस्ट्रॉय: दुर्भाग्य से, MyISAM का उपयोग हर जगह किया जाता है, और मैं DBA नहीं हूं।
static_rtti

1
Sql कथन जोड़ा गया :)
इमाद मोक्कादेम

11

मुझे पता है कि यह अन्य उत्तरों का दोहराव है, लेकिन परीक्षण अद्यतन के लिए अतिरिक्त कदम उठाने के लिए कुछ भावनात्मक समर्थन है: डी

परीक्षण अपडेट के लिए, हैश # आपका मित्र है।

यदि आपके पास अपडेट स्टेटमेंट है:

UPDATE 
wp_history
SET history_by="admin"
WHERE
history_ip LIKE '123%'

आपके पास परीक्षण के लिए अद्यतन और सेट है, तो उन्हें वापस में हैश करें:

SELECT * FROM
#UPDATE
wp_history
#SET history_by="admin"
WHERE
history_ip LIKE '123%'

यह सरल कथनों के लिए काम करता है।

एक अतिरिक्त व्यावहारिक रूप से अनिवार्य समाधान है, जब भी उत्पादन तालिका पर अद्यतन का उपयोग करके एक प्रति (बैकअप डुप्लिकेट) प्राप्त करना। Phpmyadmin> संचालन> कॉपी: table_yearmonthday। यह केवल तालिकाओं के लिए कुछ सेकंड लेता है <= 100M।


5

कोई सीधा जवाब नहीं है, लेकिन मैंने कई बोरेड ठेस वाली डेटा स्थितियों को देखा है, जिन्हें पहले क्लॉज टाइप करकेWHERE टाला जा सकता था ! कभी-कभी एक WHERE 1 = 0कार्य विवरण को सुरक्षित रूप से एक साथ रखने में भी मदद मिल सकती है। और एक अनुमानित निष्पादन योजना को देखते हुए, जो प्रभावित पंक्तियों का अनुमान लगाएगा, उपयोगी हो सकता है। इसके अलावा, एक लेनदेन में जिसे आप वापस लेते हैं जैसा कि दूसरों ने कहा है।


2
@SystemParadox - कुछ भी नहीं है, हालांकि WHERE 1 = 0अधिक पोर्टेबल है अगर कोई इस पार आता है जो एक अलग DBMS के साथ काम कर रहा है। उदाहरण के लिए, SQL सर्वर स्वीकार नहीं करेगा WHERE FALSE
डेविड एम।

2

इन मामलों में जिन्हें आप परीक्षण करना चाहते हैं, यह केवल वर्तमान कॉलम मानों और जल्द-से-अद्यतित स्तंभ मानों पर ध्यान केंद्रित करने के लिए एक अच्छा विचार है ।

कृपया निम्नलिखित कोड पर एक नज़र डालें जो मैंने WHMCS कीमतों को अद्यतन करने के लिए लिखा है:

# UPDATE tblinvoiceitems AS ii

SELECT                        ###  JUST
    ii.amount AS old_value,   ###  FOR
    h.amount AS new_value     ###  TESTING
FROM tblinvoiceitems AS ii    ###  PURPOSES.

JOIN tblhosting AS h ON ii.relid = h.id
JOIN tblinvoices AS i ON ii.invoiceid = i.id

WHERE ii.amount <> h.amount   ### Show only updatable rows

# SET ii.amount = h.amount

इस तरह हम स्पष्ट रूप से पहले से मौजूद मूल्यों बनाम नए मूल्यों की तुलना करते हैं।


1

whereअद्यतन क्वेरी में आपके द्वारा लागू की जा रही सभी शर्तों के साथ एक ही तालिका पर चयनित क्वेरी चलाएँ ।


0

SELECTइसे बनाओ ,

जैसे अगर आपको मिल गया

UPDATE users SET id=0 WHERE name='jan'

इसे रूपांतरित करें

SELECT * FROM users WHERE name='jan'

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.