2013-01-10 18 views
6

कुछ समय के लिए वेब के चारों ओर देख रहे थे और ऐसा लगता है कि मैं जो भी चाहता हूं उसके समान कुछ भी नहीं कर पा रहा हूं। मुझे पता है कि जिस तरह से मैं अपनी क्वेरी लिख रहा हूं, उससे कुछ करना है लेकिन किसी भी मदद की सराहना की जाएगी।MYSQL INSERT या अद्यतन अगर

मुझे क्या करना है कोशिश कर रहा हूँ की मूल बातें है:

  • एक तालिका में कुछ आइटम सम्मिलित करें यदि यह मौजूद नहीं है
  • अद्यतन एक आइटम यदि वह मौजूद

यह मौजूद है करता है प्रारूप में:

नाम, बारकोड, आइटम, मात्रा, स्थान, मूल्य और दिनांक

नाम - कई पंक्तियों में इस्तेमाल किया जा सकता बारकोड - एक विशिष्ट आइटम के लिए है, लेकिन कई स्थानों के रूप में आइटम इस्तेमाल किया जा सकता - बारकोड के रूप में ही है, लेकिन नाम मात्रा में शामिल है - आत्म व्याख्यात्मक स्थान - इस अलग-अलग स्थानों हो सकता है मूल्य - यह एक विशिष्ट आइटम दिनांक से जुड़ा हुआ है - पिछली बार जब आइटम खरीदा गया था

मुश्किल बात यह है कि, "नाम" में अलग-अलग कीमतों के लिए विभिन्न स्थानों पर कई आइटम (बारकोड और आइटम) हो सकते हैं। विचार यह है कि एक ग्राहक देख सकता है कि उन्होंने एक निश्चित समय पर एक वस्तु कितनी खरीदी है, इसलिए उन्हें पता है कि उन्हें इसे बेचने की कितनी आवश्यकता होगी।

हालांकि, जिस कीमत पर उन्होंने इसे खरीदा है वह भिन्न हो सकता है, इसलिए यदि कीमत पिछले खरीद से अलग है तो उन्हें तालिका में एक और पंक्ति बनाने की आवश्यकता है।

पूरी बात के पीछे विचार यह रिकॉर्ड करने के लिए है कि प्रत्येक स्थान पर प्रत्येक आइटम का "नाम" कितना है और उसके बाद उन्होंने इसे खरीदा है और जब उन्होंने इसे खरीदा था।

आशा है कि यह समझ में आता है।

छद्म कोड में:

Insert into table if does not exist 
    - name, barcode, item, quantity, location, price and date 
    If name, barcode, item, location and price are the same 
    - Update quantity and date (if more recent) 

उत्तर

11

सबसे पहले, नाम, बारकोड, मद, स्थान और कीमत पर एक UNIQUE बाधा जोड़ें।

ALTER TABLE tableX 
    ADD CONSTRAINT tableX_UQ 
    UNIQUE (name, barcode, item, location, price) ; 

तो फिर तुम INSERT INTO ... ON DUPLICATE KEY UPDATE उपयोग कर सकते हैं:

INSERT INTO tableX 
    (name, barcode, item, location, price, quantity, date) 
VALUES 
    (?, ?, ?, ?, ?, ?, ?) 
ON DUPLICATE KEY UPDATE 
    quantity = CASE WHEN VALUES(date) > date 
       THEN quantity + VALUES(quantity)  -- add quantity 
       ELSE quantity       -- or leave as it is 
      END 
, date = CASE WHEN VALUES(date) > date 
       THEN VALUES(date) ;      -- set date to new date 
       ELSE date        -- or leave as it is 
      END 

REPLACE भी इस्तेमाल किया जा सकता है, लेकिन वहाँ (यदि आप विदेशी कुंजी है, जो विशेष रूप से कोई फर्क) व्यवहार में मतभेद हैं। जानकारी के लिए, इस सवाल का “INSERT IGNORE” vs “INSERT … ON DUPLICATE KEY UPDATE” और जो INSERT IGNORE के बीच मतभेद की चर्चा @Bill Kawin से जवाब है, INSERT ... ON DUPLICATE KEY और REPLACE देखते हैं।

+0

बढ़िया, जोड़ा पाने में कामयाब रहे कि हालांकि काम कर रहा है, अगर मैं केवल इसे अद्यतन करने अगर तारीख नए तो मौजूदा एक है चाहता हूँ, क्या आवश्यकता होगी करने के लिए जा सकता है? – roadkill247

+0

और यदि यह नया नहीं है, तो तिथि को छोड़ दें? और केवल मात्रा बदलें? या दोनों unaltered छोड़ दो (तो उस मामले में कुछ भी नहीं है)? –

+0

हाय ypercude, हाँ अगर तारीख कोई नया नहीं है तो दोनों unaltered – roadkill247

4

आप mysql में replace वाक्यविन्यास का उपयोग कर सकते हैं।

लेकिन यह केवल एक अद्वितीय इंडेक्स के साथ काम करेगा ... फ़ील्ड अद्वितीय होने की आवश्यकता है।

alter <yourtable> add unique index(name, barcode, item, location, price); 

फिर अपने सम्मिलित/अपडेट वाक्य रचना

replace into <yourtable> (name, barcode, item, quantity, location, price, date) 
VALUES('name1', 'barcode1', 2, 'location1', 12.0, '25/12/2012'); 

संपादित करें संग्रहीत की

उदाहरण बन जाएगा:

तो तुम ऐसे ही एक अनूठा सूचकांक बनाने के लिए होगा प्रक्रिया (सरलीकृत और अवांछित):

DELIMITER && 
DROP PROCEDURE IF EXISTS MyBase.UpdateOrInsert $$ 
CREATE PROCEDURE MyBase.UpdateOrInsert 
(
    IN _name VARCHAR(10), 
    IN _barcode VARCHAR(50), 
    IN _quantity INTEGER 
    IN _date DATE 
) 

DECLARE existingDate DATE default NULL; 
BEGIN 

SELECT date 
INTO existingDate 
FROM <yourTable> where name = _name and barcode = _barcode; 

if (existingDate IS NULL) then 
    insert into <yourtable> (name, barcode, quantity, date) VALUES(_name, _barcode, _qantity, _date); 
else 
    if (existingDate < _date) then 
    update <yourtable> 
    set quantity = _quantity, 
     date = _date 
    where name = _name 
    and barcode = _barcode; 
    end if; 
end if; 
END && 
+0

उत्तर के लिए धन्यवाद, एक और उपयोगी उत्तर, हालांकि अगर मैं इसके अतिरिक्त जोड़ना चाहता हूं तो मात्रा केवल तभी अपडेट की जाएगी जब तिथि नई हो तो तालिका में वर्तमान वाला? चूंकि मैं एक एक्सएमएल फ़ाइल पार्स कर रहा हूं इसलिए कुछ डेटा – roadkill247

+0

@ रोडकिल्ल 247 को फिर से पढ़ा गया है, मुझे लगता है कि आप इसे या तो यपरक्यूब के उत्तर के साथ नहीं कर सकते हैं ... मैं कहूंगा कि आपको संग्रहीत प्रक्रिया के लिए जाना होगा । या डेटाबेस में जाने से पहले, अपनी एक्सएमएल फ़ाइल की पार्सिंग में प्रबंधित करें ... अद्वितीय इंडेक्स (जो दोनों उत्तरों का आधार है) का कारण विशिष्टता का प्रबंधन कर सकता है, न कि "अधिक"/"कम" स्थितियां। –

+0

त्वरित उत्तर के लिए धन्यवाद। एक्सएमएल मैं बदल नहीं सकता क्योंकि यह किसी तीसरे पक्ष द्वारा प्रदान किया जाता है, इसलिए जब आप एक संग्रहीत प्रक्रिया कहते हैं तो आपका क्या मतलब है? – roadkill247

1

अंत में मिले समाधान से ऊपर की सभी मदद के लिए धन्यवाद, दोनों के बहुत करीब थे। यह नीचे खोजें:

INSERT INTO `stock` 
    (name, barcode, item, quantity, location, price, date) 
VALUES 
    (?,?,?,?,?,?,?)       
ON DUPLICATE KEY UPDATE 
    quantity = CASE WHEN 
       VALUES(date) < $date 
       THEN quantity + $quantity 
       ELSE quantity 
       END, 
    date = CASE WHEN 
       VALUES(date) < $date 
       THEN VALUES(date) 
       ELSE $date 
       END 
+0

हालांकि इसका उपयोग कुछ दिलचस्प हो गया है, जब मैंने थोड़ी सी मात्रा का उपयोग किया, तो यह ठीक काम करता है, हालांकि बड़ी मात्रा में मात्रा अद्यतन होती है भले ही तिथि अंतिम तिथि के बराबर होती है – roadkill247

संबंधित मुद्दे