2010-03-17 20 views
15

का हवाला देते हुए MySQL सम्मिलित मैनुअल के साथ एक MySQL सम्मिलित/अपडेट बयान तैयार कर रहा है - एक ही अद्यतन के लिए चला जाता है:मूलभूत मूल्यों

Use the keyword DEFAULT to set a column explicitly to its default value. This makes it easier to write INSERT statements that assign values to all but a few columns, because it enables you to avoid writing an incomplete VALUES list that does not include a value for each column in the table. Otherwise, you would have to write out the list of column names corresponding to each value in the VALUES list.

कम अगर मैं कॉलम 2 के रूप में सेट के साथ

INSERT INTO table1 (column1,column2) values ('value1',DEFAULT); 

एक नई पंक्ति लिखने में

तो इसका डिफ़ॉल्ट मान - जो भी हो सकता है - डाला गया है।

लेकिन अगर मैं तैयार करने और PHP में एक बयान निष्पादित करें:

$statement = $pdoObject-> 
    prepare("INSERT INTO table1 (column1,column2) values (?,?)"); 
$statement->execute(array('value1','DEFAULT')); 

नई पंक्ति अपने पाठ मान के रूप में 'डिफ़ॉल्ट' में शामिल होंगे - अगर स्तंभ पाठ मान संग्रहीत करने में सक्षम है।

अब मैं पीडीओ के लिए एक अमूर्त परत (मैं इसे आवश्यक) और इस समस्या के समाधान प्राप्त करने के लिए लिखा है एक

const DEFAULT_VALUE = "randomstring"; 

पेश करने पर विचार कर रहा हूँ तो मैं इस तरह के बयानों पर अमल कर सकते हैं:

$statement->execute(array('value1',mysql::DEFAULT_VALUE)); 

और फिर विधि में जो बाध्यकारी करता है मैं उन मानों के माध्यम से जाता हूं जिन्हें बाध्य किया जाता है और यदि कुछ self::DEFAULT_VALUE के बराबर हैं, तो तदनुसार कार्य करें।

मुझे यकीन है कि ऐसा करने का एक बेहतर तरीका है। क्या किसी और को इसी तरह की स्थितियों का सामना करना पड़ा है?

+0

के बाद से पीडीओ अपने मूल्यों संसाधित कर रहा है के रूप में तार इनपुट होने के लिए देखते हैं अगर यकीन नहीं है, यह आप को बदलने के लिए हो सकता है की तरह लग रहा थोड़ा सा कोड, अगर यह संभव है। आप इसे बदल सकते हैं ताकि आप '... execute (array ('\' value1 \ '', 'DEFAULT') टाइप करें), लेकिन मुझे लगता है कि पीडीओ आपके लिए इन मानों को 'mysql_real_escape_string() के साथ संसाधित कर रहा है ', आदि। यह उस समारोह को हरा देगा। आपको शायद इसे सीधे 'तैयार()' तर्क में डालना होगा। – Jonah

+1

क्यों न केवल आपके 'INSERT' कथन में कॉलम शामिल करें कि आप डिफ़ॉल्ट के अलावा किसी अन्य मान पर सेट कर रहे हैं? –

+1

समस्या 'अद्यतन' और एक खाली सबमिट इनपुट के साथ है। मुझे इसे डिफ़ॉल्ट फ़ील्ड की आवश्यकता है, उदाहरण के लिए '0000-00-00' उदाहरण फ़ील्ड के लिए जब' '' 'नया मान के रूप में सेट किया गया हो। – raveren

उत्तर

8

केवल "वैकल्पिक हल" मैं इस के लिए पता उपयोग करने के लिए है Coalesce() और Default(fieldname)

जैसे

$pdo = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$pdo->exec(" 
    CREATE TEMPORARY TABLE foo (
    id int auto_increment, 
    x int NOT NULL DEFAULT 99, 
    y DATETIME NOT NULL DEFAULT '2010-03-17 01:00:00', 
    z varchar(64) NOT NULL DEFAULT 'abc', 
    primary key(id) 
) 
"); 


$stmt = $pdo->prepare(' 
    INSERT INTO 
    foo 
    (x,y,z) 
    VALUES 
    (
     Coalesce(:x, Default(x)), 
     Coalesce(:y, Default(y)), 
     Coalesce(:z, Default(z)) 
    ) 
'); 
$stmt->bindParam(':x', $x); 
$stmt->bindParam(':y', $y); 
$stmt->bindParam(':z', $z); 


$testdata = array(
    array(null, null, null), 
    array(1, null, 'lalala'), 
    array(null, '2009-12-24 18:00:00', null) 
); 
foreach($testdata as $row) { 
    list($x,$y,$z) = $row; 
    $stmt->execute(); 
} 
unset($stmt); 
foreach($pdo->query('SELECT id,x,y,z FROM foo', PDO::FETCH_NUM) as $row) { 
    echo join(', ', $row), "\n"; 
} 

प्रिंट

1, 99, 2010-03-17 01:00:00, abc 
2, 1, 2010-03-17 01:00:00, lalala 
3, 99, 2009-12-24 18:00:00, abc 
+1

डिफ़ॉल्ट (x) डिफॉल्ट हो सकता है, यदि कॉलम नाम का उल्लेख करने की कोई आवश्यकता नहीं है, तो आप उसी कॉलम में इस कॉलम के लिए डिफ़ॉल्ट मान चाहते हैं। यह त्रुटि है। अद्यतन टी सेट एक्स = DEFAULT; –

+0

महान सोच! सही नहीं है लेकिन मेरा समाधान धड़कता है! – raveren

+3

@ फ्रैंक: Coalesce() को तर्क के रूप में उपयोग किए जाने पर इसे डिफ़ॉल्ट (फ़ील्डनाम) होना चाहिए। – VolkerK

0

कोशिश बदलते इस:

$statement = $pdoObject-> 
    prepare("INSERT INTO table1 (column1,column2) values (?,?)"); 
$statement->execute(array('value1','DEFAULT')); 
इस के लिए

:

$statement = $pdoObject-> 
    prepare("INSERT INTO table1 (column1,column2) values (?,DEFAULT)"); 
$statement->execute(array('value1')); 

मुझे ऐसा लगता है कि अपने मूल कोड आप दे देंगे इस:

INSERT INTO table1 (column1,column2) values ('value1','DEFAULT') 

मेरे कोड आप देना चाहिए यह:

INSERT INTO table1 (column1,column2) values ('value1',DEFAULT) 
+0

वैसे भी अन्य मूल्य भी चाहते हैं लेकिन डिफ़ॉल्ट रूप से डिफ़ॉल्ट। – raveren

1

मैं VolkerK जवाब का जवाब दे रहे कोशिश की, लेकिन लगता है कि कैसे सके। :(मैं वैसे भी यह सब करने के लिए थोड़े नया हूँ

, मैं उसके COALESCE विचार के साथ conjuction में उपयोग करने के लिए

CREATE FUNCTION NULLDEFAULT(colname VARCHAR(64), tablename VARCHAR(64), dbname VARCHAR(64)) RETURNS longtext DETERMINISTIC READS SQL DATA 
BEGIN 
    DECLARE retval longtext; 
    SELECT 
     COLUMN_DEFAULT INTO retval 
    FROM 
     information_schema.COLUMNS 
    WHERE 
     TABLE_NAME = tablename 
    AND 
     COLUMN_NAME = colname 
    AND 
     TABLE_SCHEMA = dbname; 

    RETURN retval; 
END 

आप इस तरह यह प्रयोग करेंगे एक mysql समारोह बनाया:।

$stmt = $pdo->prepare(" 
    INSERT INTO 
    foo 
    (x,y,z) 
    VALUES 
    (
     Coalesce(:x, NULLDEFAULT('x', 'foo', 'database')), 
     Coalesce(:y, NULLDEFAULT('y', 'foo', 'database')), 
     Coalesce(:z, NULLDEFAULT('z', 'foo', 'database')) 
    ) 
"); 

अगर कॉलम का कोई डिफ़ॉल्ट मान नहीं है, तो यह शून्य हो जाएगा, और "कॉलम का कोई डिफ़ॉल्ट मान नहीं है" त्रुटि ट्रिगर नहीं करेगा।

बेशक

आप इसे संशोधित कर सकता है डेटाबेस पैरामीटर

+0

मुझे नहीं लगता कि यह प्रदर्शन के अनुसार होगा। AFAIK mysql फ़ंक्शंस के परिणामों को कैश नहीं करेगा, इसलिए आप अपनी क्वेरी को प्रत्येक पंक्ति और सम्मिलित क्वेरी में प्रत्येक कॉलम के लिए कॉल करेंगे। डिफ़ॉल्ट रूप से PHP के माध्यम से डिफ़ॉल्ट मान प्राप्त करना बेहतर होता है, लेकिन जैसा कि मैंने पहले से ही निष्कर्ष निकाला है, यहां मेरा सबक डिफ़ॉल्ट mysql मानों पर भरोसा नहीं करना है। मैं अभी भी प्रयास के लिए आपको एक +1 दूंगा। – raveren

+0

दस्तावेज़ीकरण के मुताबिक डिटेरमिनिस्टिक कीवर्ड mysql को बताता है कि फ़ंक्शन हमेशा एक ही पैरामीटर के साथ समान मान लौटाता है, जिससे मुझे विश्वास होता है कि यह परिणाम कैश करेगा। लेकिन मैंने इसे बड़े पैमाने पर स्वाद नहीं लिया है, मैं गति में किसी भी उल्लेखनीय कमी के बिना इसे एक छोटे से इंट्रानेट में उपयोग कर रहा हूं। –

0

मुझे लगता है कि यह है कि यह स्ट्रिंग 'डिफ़ॉल्ट' लिख रहा है, क्योंकि यह पीडीओ से बच रहा है तो वहाँ bindvalue के लिए parametres जहां के प्रकार को निर्दिष्ट कर सकते हैं की आवश्यकता नहीं करने के लिए दिया गया मूल्य ताकि आप कोई उद्धरण के साथ शून्य भेज सकें और यह पीडीओ :: PARAM_NULL होगा; और फिर डिफ़ॉल्ट मान रखा जाएगा, लेकिन मैं इसी तरह के मानकों को जब साथ बंधन को अंजाम

if(is_int($param)){$pdoParam = PDO::PARAM_INT;} 
     elseif(is_bool($param)){$pdoParam = PDO::PARAM_BOOL;} 
     elseif(is_null($param)){ $pdoParam = PDO::PARAM_NULL;} 
     elseif(is_string($param)){$pdoParam = PDO::PARAM_STR;} 
            else{$pdoParam = FALSE;} 
       $this->_query->bindValue($k,$param,$pdoParam); 
+0

'$ pdoParam = गलत है, 'प्राप्त करने के लिए क्या माना जाता है? डिफ़ॉल्ट 'PARAM_STR' है। – DanMan

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