MySQL, जाँच करें कि क्या SQL के साथ टेबल में कोई कॉलम मौजूद है


130

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

मैंने कुछ ऐसा सोचा

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
           WHERE TABLE_NAME='prefix_topic' AND column_name='topic_last_update') 
BEGIN 
ALTER TABLE `prefix_topic` ADD `topic_last_update` DATETIME NOT NULL;
UPDATE `prefix_topic` SET `topic_last_update` = `topic_date_add`;
END;

काम करेगा, लेकिन यह बुरी तरह से विफल है। क्या उधर रास्ता है?



सिर्फ इसे क्यों नहीं बनाया? यदि यह मौजूद है, तो निर्माण विफल हो जाएगा लेकिन आपको परवाह नहीं है।
ब्रायन हूपर

सृजन एक सौदे के अंदर जगह लेता है और विफलता पूरे लेन-देन, दुख की बात है, लेकिन सच को समाप्त कर देगा
clops

@haim - हेडअप के लिए धन्यवाद, लेकिन आपके लिंक में सुझाई गई क्वेरी केवल एक प्रक्रिया के अंदर काम करती है :(
clops

2
डीडीएल के बयानों से वर्तमान लेनदेन में निहित कमी होती है। dev.mysql.com/doc/refman/5.0/en/implicit-commit.html
Mchl

जवाबों:


259

यह मेरे लिए अच्छा काम करता है।

SHOW COLUMNS FROM `table` LIKE 'fieldname';

PHP के साथ यह कुछ इस तरह होगा ...

$result = mysql_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'");
$exists = (mysql_num_rows($result))?TRUE:FALSE;

8
सवाल यह नहीं है कि php + sql या java + sql का उपयोग कैसे किया जाए, यह कैसे करना है कि शुद्ध sql / mysql का उपयोग करना है इसलिए
डाउनवोट

61
आप इस प्रश्न का उत्तर देते हैं + कुछ जानकारी जिसने मुझे और शायद दूसरों की मदद की, +1
फ्रांसिस्को प्रेसेनिया

@Mfoo धन्यवाद Mfoo, आपने मेरा दिन बचा लिया! आकर्षण की तरह काम करता है। इस कार्य के लिए प्रक्रियाएं बनाने के अलावा सबसे अच्छे समाधानों में से एक।
वेबब्लोवर

8
Yura: शुद्ध SQL / MySQL का उत्तर पहला भाग है, जहां वह कहता है कि "SHOW COLUMNS FROM table LIKE 'fieldname' का उपयोग करें।" आप PHP कोड की अवहेलना कर सकते हैं, यदि आप PHP का उपयोग कर रहे हैं तो परिणाम को पुनः प्राप्त करने और व्याख्या करने का केवल एक ही तरीका है।
orrd

1
@ codenamezero मुझे लगता है कि आप MSSQL का उपयोग करने की बात कर रहे हैं, यह सवाल MySQL से संबंधित था। MSSQL के लिए इस पोस्ट का संदर्भ लें
Mfoo

158

@julio

SQL उदाहरण के लिए धन्यवाद। मैंने क्वेरी की कोशिश की और मुझे लगता है कि इसे ठीक से काम करने के लिए एक छोटे से बदलाव की आवश्यकता है।

SELECT * 
FROM information_schema.COLUMNS 
WHERE 
    TABLE_SCHEMA = 'db_name' 
AND TABLE_NAME = 'table_name' 
AND COLUMN_NAME = 'column_name'

मेरे लिए वह काम कर गया।

धन्यवाद!


यह मेरे सीमित अनुसंधान से प्रतीत होता है कि सभी होस्टिंग वातावरण में एक सूचना नहीं है_केम डीबी। सभी cpanel वातावरण मैं इसे इस्तेमाल किया है। यह उपलब्ध समाधान इस डीबी मौजूदा पर निर्भर करता है।
cardi777

2
यह उत्तर "SHOW COLUMNS" का उपयोग करने से बेहतर है क्योंकि यह SHOW COLUMNS के विपरीत ANSI मानक तरीके का उपयोग करता है, जो MySQL के लिए विशिष्ट है। तो यह समाधान अन्य डेटाबेस के साथ काम करेगा। "Information_schema" का उपयोग करना अजीब लगता है और आपको लगता है कि ऐसा करने के लिए यह मानक SQL तरीका नहीं होगा, लेकिन यह है।
orrd

5
ध्यान दें कि यह उत्तर केवल आपको स्तंभ के अस्तित्व के बारे में जानकारी देता है। यदि आप सशर्त रूप से कुछ डीडीएल कथनों को निष्पादित करना चाहते हैं, तो आपको पूरी प्रक्रिया को एक प्रक्रिया में लपेटना होगा IF, जैसे कि स्टेटमेंट की अनुमति देता है , आदि। stackoverflow.com/questions/7384711/… उदाहरण के लिए कि कैसे एक प्रक्रिया को चारों ओर लपेटने के लिए। स्तंभ और सशर्त डीएमएल बयान के लिए परीक्षण।
क्रिस्टोफर शुल्त्स

@ मुख्य: stackoverflow.com/questions/32962149/… मैंने आपके उत्तर का हवाला दिया है
अमर सिंह

यह नीचे दिए गए "SHOW COLUMNS" दृष्टिकोण से अच्छा है जैसा कि SQL इंजेक्शन के जोखिम को कम करने वाले मानकीकृत प्रश्नों में इस्तेमाल किया जा सकता है। बस आप जोड़ना चाहते हैं TAT_SCHEMA कॉलम को पॉप्युलेट करने के लिए DATABASE () फ़ंक्शन का उपयोग कर सकते हैं।
एंड्रयू

16

बस जो कोई @Mchl का वर्णन कर रहा था, उसके ठोस उदाहरण की तलाश में मदद करने के लिए, कुछ ऐसा करने का प्रयास करें

SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'my_schema' AND TABLE_NAME = 'my_table' AND COLUMN_NAME = 'my_column'

यदि यह गलत (शून्य परिणाम) देता है तो आपको पता है कि कॉलम मौजूद नहीं है।


2
मेरा मानना ​​है कि यह होना चाहिए TABLE_NAME = 'my_table', TABLE_SCHEMA स्कीमा तालिका में है। यानीSELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = 'my_schema' AND TABLE_NAME = 'my_table' AND COLUMN_NAME = 'my_column'
एरोनहोलैंड

10

निम्नलिखित जानकारी के बिना सादे PHP का उपयोग करने का दूसरा तरीका निम्नलिखित है: डेटाबेस

$chkcol = mysql_query("SELECT * FROM `my_table_name` LIMIT 1");
$mycol = mysql_fetch_array($chkcol);
if(!isset($mycol['my_new_column']))
  mysql_query("ALTER TABLE `my_table_name` ADD `my_new_column` BOOL NOT NULL DEFAULT '0'");

आप information_schema के उपयोग से क्यों बचना चाहेंगे? यह सिर्फ इस उद्देश्य के लिए मौजूद है। (साथ ही, यह धागा काफी पुराना है और पहले से ही उत्तर दिया गया था।)
लेह

1
मेरे परीक्षणों में, यह information_schema का उपयोग करने की तुलना में लगभग 10-50x तेज है। यह आवश्यक है कि तालिका में कम से कम एक पंक्ति हो, जिसे आप हमेशा गारंटी नहीं दे सकते।
मार्टिजन

isset()यदि सरणी कुंजी मौजूद है, लेकिन 'झूठी' को फेंक देगा, लेकिन मान NULL है । यह बेहतर है कि array_key_exists()जैसेif( !array_key_exists( 'my_new_column', $mycol ) )
पॉल गिस्लर

1
इस जवाब ने मुझे चेहरा बना दिया क्योंकि मैंने एक साधारण isset()जाँच को अनदेखा कर दिया था । यह प्रश्न को हल नहीं करता है, लेकिन यह बेहतर है यदि आपको पहले से ही चुनिंदा क्वेरी को निष्पादित करने की आवश्यकता है और इसका परिणाम मेमोरी में है।
साइफन

10

मैंने इस संग्रहित प्रक्रिया को @ lain की टिप्पणियों के ऊपर शुरू से ही एक साथ फेंक दिया, अच्छा लगा अगर आपको इसे कुछ समय से अधिक (और php की आवश्यकता नहीं):

delimiter //
-- ------------------------------------------------------------
-- Use the inforamtion_schema to tell if a field exists.
-- Optional param dbName, defaults to current database
-- ------------------------------------------------------------
CREATE PROCEDURE fieldExists (
OUT _exists BOOLEAN,      -- return value
IN tableName CHAR(255),   -- name of table to look for
IN columnName CHAR(255),  -- name of column to look for
IN dbName CHAR(255)       -- optional specific db
) BEGIN
-- try to lookup db if none provided
SET @_dbName := IF(dbName IS NULL, database(), dbName);

IF CHAR_LENGTH(@_dbName) = 0
THEN -- no specific or current db to check against
  SELECT FALSE INTO _exists;
ELSE -- we have a db to work with
  SELECT IF(count(*) > 0, TRUE, FALSE) INTO _exists
  FROM information_schema.COLUMNS c
  WHERE 
  c.TABLE_SCHEMA    = @_dbName
  AND c.TABLE_NAME  = tableName
  AND c.COLUMN_NAME = columnName;
END IF;
END //
delimiter ;

के साथ काम करना fieldExists

mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_option', NULL) //
Query OK, 0 rows affected (0.01 sec)

mysql> select @_exists //
+----------+
| @_exists |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_options', 'etrophies') //
Query OK, 0 rows affected (0.01 sec)

mysql> select @_exists //
+----------+
| @_exists |
+----------+
|        1 |
+----------+

MIster @quickshiftin, बहुत बहुत धन्यवाद। यह जाँचने में मेरी मदद करता है कि यदि कोई फ़ील्ड है , तो जाँच करके , यदि कोई तालिका अपेक्षित है , तो यह जाँचने में मदद करता है ExpirationDate। 😊
Jeancarlo Fontalvo

@JeancarloFontalvo मेरी खुशी! इसके अलावा अपने mysql- निरीक्षकों परियोजना की जाँच करें जो मैंने उच्च स्तर के तरीकों के साथ स्कीमा के निरीक्षण के लिए शुरू की थी।
क्विकशिफ्टिन

1
OMG यह एक पुस्तकालय की तरह है library। साझा करने के लिए धन्यवाद मिस्टर!
जीनकार्लो फान्टालवो

8

सूचना स्कीमा से सिर्फ कॉलम_नाम चुनें और इस क्वेरी के परिणाम को चर में डालें। फिर तालिका को परिवर्तन की आवश्यकता है या नहीं, यह तय करने के लिए चर का परीक्षण करें।

पुनश्च COLOMNS तालिका के लिए TABLE_SCHEMA को निर्दिष्ट करने के लिए फोगेट न करें।


1
मैं MySQL के बजाय नया हूं, क्या आप यहां एक छोटा उदाहरण पोस्ट कर सकते हैं?
clops

2

मैं इस सरल स्क्रिप्ट का उपयोग कर रहा हूं:

mysql_query("select $column from $table") or mysql_query("alter table $table add $column varchar (20)");

यह काम करता है यदि आप पहले से ही डेटाबेस से जुड़े हैं।


यह तभी काम करेगा जब टेबल भी घटित हो, इसमें डेटा की पंक्तियाँ भी हों। लेकिन अगर मेज खाली थी, तो यह काम नहीं करेगा।
19

1
सही नहीं है, पुराने ड्राइवरों का उपयोग करता है, अगर तालिका खाली है तो काम नहीं करता, इनपुट बच नहीं गए, लेकिन मुझे पसंद है कि आपने इसे एक पंक्ति में कैसे किया। +1
मैंने एक बार एक भालू को कुश्ती दी।

1

एमफू के लिए बहुत धन्यवाद जिन्होंने टेबल में मौजूद नहीं होने पर स्तंभों को गतिशील रूप से जोड़ने के लिए वास्तव में अच्छी स्क्रिप्ट रखी। मैंने PHP के साथ उनके जवाब में सुधार किया हैस्क्रिप्ट अतिरिक्त आप पाते हैं कि कितने टेबल वास्तव में जरूरत 'ऐड स्तंभ' में मदद करता है mysql comand। बस नुस्खा का स्वाद लें। आकर्षण की तरह काम करता है।

<?php
ini_set('max_execution_time', 0);

$host = 'localhost';
$username = 'root';
$password = '';
$database = 'books';

$con = mysqli_connect($host, $username, $password);
if(!$con) { echo "Cannot connect to the database ";die();}
mysqli_select_db($con, $database);
$result=mysqli_query($con, 'show tables');
$tableArray = array();
while($tables = mysqli_fetch_row($result)) 
{
     $tableArray[] = $tables[0];    
}

$already = 0;
$new = 0;
for($rs = 0; $rs < count($tableArray); $rs++)
{
    $exists = FALSE;

    $result = mysqli_query($con, "SHOW COLUMNS FROM ".$tableArray[$rs]." LIKE 'tags'");
    $exists = (mysqli_num_rows($result))?TRUE:FALSE;

    if($exists == FALSE)
    {
        mysqli_query($con, "ALTER TABLE ".$tableArray[$rs]." ADD COLUMN tags VARCHAR(500) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL");
        ++$new;
        echo '#'.$new.' Table DONE!<br/>';
    }
    else
    {
        ++$already;
        echo '#'.$already.' Field defined alrady!<br/>';    
    }
    echo '<br/>';
}
?>

1

नमूना पीडीओ के साथ मेरे लिए यह काम:

public function GetTableColumn() {      
$query  = $this->db->prepare("SHOW COLUMNS FROM `what_table` LIKE 'what_column'");  
try{            
    $query->execute();                                          
    if($query->fetchColumn()) { return 1; }else{ return 0; }
    }catch(PDOException $e){die($e->getMessage());}     
}

0

अलर्ट के अंदर अन्य टेबल / मोडी कॉल्स या किसी भी अन्य ऐसे टेबल मॉड संचालन को न रखें। लेन-देन ALERations के लिए QUERY विफलता को वापस करने में सक्षम होने के लिए है ... यह हर बार लेनदेन में त्रुटि करेगा।

बस तालिका पर एक सेलेक्ट * क्वेरी चलाएँ और जाँचें कि क्या कॉलम है ...


ALTERMySQL में (और DDL उस तरह) वास्तव में लेनदेन करते हैं। लेकिन सेलेक्ट * का उपयोग करने से नेटवर्क में एक बड़ा ओवरहेड उत्पन्न होगा जो सिर्फ कॉलम की मौजूदगी की जाँच करेगा। आप इसके बजाय प्रयास कर सकते हैं SELECT my_col_to_check FROM t LIMIT 0: यदि mysql कोई त्रुटि उत्पन्न करता है, तो स्तंभ संभवतः मौजूद नहीं है (फिर भी, त्रुटि की जांच करें, क्योंकि यह एक नेटवर्क मुद्दा या जो भी हो सकता है!)। यदि यह कोई त्रुटि उत्पन्न करता है, तो स्तंभ मौजूद है। मुझे यकीन नहीं है कि यह कॉलम अस्तित्व के लिए सबसे अच्छा तरीका है।
एक्सनोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.