2011-10-20 12 views
5

से अल्पविराम से अलग सूची में मूल्यों को निकालें मेरे पास 'my' नामक मेरे MySQL डेटाबेस में एक तालिका है। उस तालिका में 'इच्छाओं' नामक एक पंक्ति है (बच्चे की इच्छासूची वस्तुओं की एक अल्पविराम से अलग सूची)। मुझे उस सूची को अपडेट करने में सक्षम होना चाहिए ताकि यह केवल एक मान हटा सके। यानी सूची = आकार 12 नियमित जींस, सर्फबोर्ड, रेड सॉक्स बेसबॉल कैप; मैं सर्फबोर्ड को हटाना चाहता हूं।डेटाबेस

मेरे प्रश्न अभी इस

$select = mysql_query('SELECT * FROM children WHERE caseNumber="'.$caseNum.'" LIMIT 1 '); 
    $row = mysql_fetch_array($select); 

    foreach ($wish as $w) { 
     $allWishes = $row['wishes']; 
     $newWishes = str_replace($w, '', $allWishes); 
     $update = mysql_query("UPDATE children SET wishes='$newWishes' WHERE caseNum='".$caseNum."'"); 
} 

की तरह दिखता है लेकिन अद्यतन क्वेरी कुछ हटाये नहीं है। मैं क्या कर सकता हूं जो मुझे चाहिए?

+5

मुझे लगता है कि इच्छाओं को अपने आप मेज और कुंजी caseNumber साझा करते हुए यहाँ वापस जुड़ा हुआ होना चाहिए। –

+0

1 स्ट्रिंग कॉन्सटेनेशन गायब होने लगता है लेकिन एक बार जब इसे हल किया जाता है तो आप इस क्वेरी को एसक्यूएल इंजेक्शन के लिए खोल रहे हैं - एक हैकर वास्तव में वह चाहता है जो उन्होंने चाहते थे। – Andrew

+0

@ डैरेन - वास्तव में सही जवाब है, डीबी मॉडल गलत है और इसे ठीक करने की आवश्यकता है। टिप्पणियों पर दयालु उपरांत – Andrew

उत्तर

3

these user-defined REGEXP_REPLACE() functions उपयोग करके, आप एक खाली स्ट्रिंग से बदलने के लिए सक्षम हो सकता है:

UPDATE children SET wishes = REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '') WHERE caseNum='whatever'; 

दुर्भाग्य से, तुम सिर्फ सादे पुराने REPLACE() उपयोग नहीं कर सकते क्योंकि आप जहां स्ट्रिंग में 'सर्फबोर्ड' प्रतीत होता है पता नहीं है। वास्तव में, अगर 'सर्फबोर्ड' शुरुआत या अंत में होता है तो उपरोक्त रेगेक्स को शायद अतिरिक्त ट्वीकिंग की आवश्यकता होगी।

शायद आप बंद ट्रिम कर सकता है प्रमुख और अल्पविराम के इस तरह बचे अनुगामी:

UPDATE children SET wishes = TRIM(BOTH ',' FROM REGEXP_REPLACE(wishes, '(,(\s)?)?Surfboard', '')) WHERE caseNum='whatever'; 

तो क्या यहाँ हो रहा है? रेगेक्स 'सर्फबोर्ड' और इससे पहले एक वैकल्पिक कॉमा & स्थान हटा देता है। फिर आसपास के TRIM() फ़ंक्शन स्ट्रिंग की शुरुआत में 'सर्फबोर्ड' होने पर संभावित संभावित अल्पविराम को समाप्त करता है। शायद इसे रेगेक्स द्वारा भी संभाला जा सकता है, लेकिन स्पष्ट रूप से, मैं इसे समझने के लिए बहुत थक गया हूं।

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

अद्यतन

इस अधिक के बारे में सोच, मैं और अधिक बस के उपयोग के लिए मजबूर कर रहा करने के लिए आंशिक हूँ। यह दो कॉमा पक्ष की तरफ देख रहा है, हालांकि आपकी मूल सूची वस्तुओं को अलग करने की कोई जगह नहीं थी। यदि वस्तुओं को अल्पविराम और रिक्त स्थान से अलग किया गया था, तो बाहरी REPLACE() कॉल में ',,'', ,' को बदलें।

UPDATE children SET wishes = TRIM(BOTH ',' FROM REPLACE(REPLACE(wishes, 'Surfboard', ''), ',,', ',')) WHERE caseNum='whatever'; 
1

आपके प्रश्न का सही उत्तर नहीं है, लेकिन डैरेन की तरह यह कहता है कि यह अपनी तालिका के रूप में बेहतर होना चाहता है। तो आप 3 टेबल है हो सकता है कि आप अपने डेटाबेस स्कीमा को बदल सकता है, उदाहरण के लिए:

children 
-> caseNum 
-> childName 

wishes 
-> caseNum 
-> wishId 
-> wishName 

childrensWishes 
-> caseNum 
-> wishId 

तब जोड़ सकते हैं या एक बच्चे के लिए एक इच्छा को हटाने के लिए, आप को जोड़ या childrensWishes से प्रासंगिक पंक्ति हटाएं। आपके वर्तमान डिज़ाइन में हेरफेर करना मुश्किल हो जाता है (जैसा कि आप ढूंढ रहे हैं), साथ ही आपको असंगत डेटा के लिए जोखिम में छोड़ देता है।

अधिक प्रत्यक्ष उत्तर के रूप में, आप इच्छाओं की सूची प्राप्त करके अपने मौजूदा तरीके को ठीक कर सकते हैं, उन्हें विस्फोट() 'कर सकते हैं, जिसे आप सरणी से नहीं चाहते हैं और इसे वापस कर सकते हैं) डेटाबेस को अद्यतन करने के लिए एक स्ट्रिंग।

0

मेक चाहती तालिका इस प्रारूप है:

caseNumber,wish 

तो फिर तुम इस तरह एक बच्चे की इच्छाओं के सभी मिल:

SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ? 

एक इच्छा निकाला जा रहा है हो जाता है:

DELETE from wishes where caseNumber = ? 

एक जोड़ा जा रहा है इच्छा बन जाती है:

INSERT into wishes (caseNumber,wish) values (?,?) 

एक इच्छा रिटर्निंग हो जाता है:

SELECT * FROM children c left join wishes w on c.caseNumber = w.caseNumber WHERE c.caseNumber= ? LIMIT 1 
0

इच्छाओं एक सरणी जिसे बाद में धारावाहिक रूप है एक विचार हो सकता है में सूचीबद्ध होने, अन्यथा आप, यह स्लाइस हिस्सा आप डॉन 'को दूर स्ट्रिंग को पुनः प्राप्त करने की आवश्यकता होगी, टी चाहते हैं, तो अवशेषों को संयोजित करें। यह explode() फ़ंक्शन का उपयोग करके किया जा सकता है।

आप एक सरणी का उपयोग करने के लिए गए थे, तो आप इस तरह एक पाश के साथ प्रकार के माध्यम से यह सरणी और उसके बाद पुनः प्राप्त होगा:

// Wishes array: 
// Array (
//  [0] Regular Jeans 
//  [1] Surfboard 
//  [2] Red Sox Baseball Cap 
//) 

$wishes = $row['wishes']; // This is a serialized array taken from the database 
$wishes = unserialize($wishes); 

foreach ($wishes as $key => $value) { 
    if ($value == 'Surfboard') { 
     unset($wishes[$key]); 
     break; 
    } 
} 

$wishes = serialize($wishes); 
// Update database 

ध्यान रखें कि सूचकांक [1] अब में मौजूद नहीं होगा सरणी, इसलिए यदि आप एक साफ सरणी सरणी के माध्यम से पाश चाहिए करना चाहते हैं और यह अपने आप में एक नई सरणी बनाने के लिए:

foreach ($wishes as $wishes) { 
    $newArray[] = $wishes; 
} 
0

मुझे लगता है कि इस तरह के मुद्दे पर सबसे अच्छा जवाब यहाँ है The best way to remove value from SET field?

क्वेरी की तरह इस जो अल्पविराम में, मान या मान, या केवल मूल्य को शामिल किया गया अलग स्तंभ

 
UPDATE yourtable 
SET 
    categories = 
    TRIM(BOTH ',' FROM 
     REPLACE(
     REPLACE(CONCAT(',',REPLACE(col, ',', ',,'), ','),',2,', ''), ',,', ',') 
    ) 
WHERE 
    FIND_IN_SET('2', categories) 

यहाँ आप जहां खंड में अपनी हालत हो सकता है किया जाना चाहिए। अधिक जानकारी के लिए उपरोक्त लिंक देखें।

0

आप इस तरह समारोह बना सकते हैं:

CREATE FUNCTION `remove_from_set`(v int,lst longtext) RETURNS longtext CHARSET utf8 
BEGIN 
set @lst=REPLACE(@lst, ',,', ','); 
set @lng=LENGTH(@lst) - LENGTH(REPLACE(@lst, ',', ''))+1; 
set @p=find_in_set(@v,@lst); 
set @l=SUBSTRING_INDEX(@lst, ',', @p-1); 
set @r=SUBSTRING_INDEX(@lst, ',', @[email protected]); 
IF @l!='' AND @r!='' THEN 
    return CONCAT(@l,',',@r); 
ELSE 
    RETURN CONCAT(@l,'',@r); 
END IF; 
END 

का उपयोग करना:

SELECT remove_from_set('1,,2,3,4,5,6',1)