यदि कोई SQLite में मौजूद नहीं है, तो टीडी ADD COLUMN पर क्लिक करें


89

हमें हाल ही में अपने मौजूदा SQLite डेटाबेस तालिकाओं में कुछ कॉलम जोड़ने की आवश्यकता है। इसके साथ किया जा सकता है ALTER TABLE ADD COLUMN। बेशक, यदि तालिका पहले ही बदल दी गई है, तो हम इसे अकेले छोड़ना चाहते हैं। दुर्भाग्य से, SQLite एक IF NOT EXISTSखंड का समर्थन नहीं करता है ALTER TABLE

हमारा वर्तमान समाधान ALTER TABLE स्टेटमेंट को निष्पादित करना और किसी भी "डुप्लिकेट कॉलम नाम" त्रुटियों को अनदेखा करना है, जैसे कि यह Python उदाहरण (लेकिन C ++ में)।

हालांकि, डेटाबेस स्कीमा की स्थापना करने के लिए हमारे सामान्य दृष्टिकोण एक .SQL स्क्रिप्ट युक्त है CREATE TABLE IF NOT EXISTSऔर CREATE INDEX IF NOT EXISTSबयान है, जो का उपयोग कर क्रियान्वित किया जा सकता sqlite3_execया sqlite3कमांड लाइन उपकरण। हम ALTER TABLEइन स्क्रिप्ट फ़ाइलों में नहीं डाल सकते हैं क्योंकि यदि यह कथन विफल हो जाता है, तो इसे निष्पादित नहीं किया जाएगा।

मैं एक ही स्थान पर तालिका परिभाषाएँ रखना चाहता हूं और .sql और .cpp फ़ाइलों के बीच विभाजन नहीं करना चाहता। क्या ALTER TABLE ADD COLUMN IF NOT EXISTSशुद्ध SQLite SQL में वर्कअराउंड लिखने का एक तरीका है ?

जवाबों:


64

मेरे पास 99% शुद्ध एसक्यूएल विधि है। विचार आपके स्कीमा को संस्करणित करना है। आप इसे दो तरीकों से कर सकते हैं:

  • PRAGMA user_versionअपने डेटाबेस स्कीमा संस्करण के लिए एक वृद्धिशील संख्या को संग्रहीत करने के लिए 'user_version' pragma कमांड ( ) का उपयोग करें ।

  • अपनी खुद की परिभाषित तालिका में अपना संस्करण संख्या स्टोर करें।

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


7
का प्रारंभिक मूल्य क्या है user_version? मैं शून्य मानती हूं, लेकिन उस दस्तावेज को देखकर अच्छा लगेगा।
क्रेग मैकक्वीन

इसके साथ भी, क्या इसे शुद्ध SQL में किया जा सकता है, क्योंकि sqlite समर्थन नहीं करता है IFऔर इसमें ALTER TABLEसशर्त नहीं है? "99% शुद्ध SQL" से आपका क्या मतलब है?
क्रेग मैकक्वीन

1
@CraigMcQueen के प्रारंभिक मूल्य के रूप में user_version, यह 0 प्रतीत होता है, लेकिन यह वास्तव में एक उपयोगकर्ता-परिभाषित मूल्य है, इसलिए आप अपना स्वयं का प्रारंभिक मूल्य बना सकते हैं।
MPelletier

7
user_versionप्रारंभिक मूल्य के बारे में प्रश्न तब प्रासंगिक होता है जब आपको मौजूदा डेटाबेस मिला हो, और आपने पहले कभी उपयोग नहीं किया हो user_version, लेकिन आप इसका उपयोग शुरू करना चाहते हैं, इसलिए आपको यह मानने की आवश्यकता है कि एक विशेष प्रारंभिक मूल्य पर सेटलाइट को सेट करें।
क्रेग मैकक्वीन

1
@CraigMcQueen मैं सहमत हूं, लेकिन यह प्रलेखित नहीं हुआ है।
MPelletier

30

एक वर्कअराउंड केवल कॉलम बनाने और अपवाद / त्रुटि को पकड़ने के लिए है जो कॉलम पहले से मौजूद है। कई कॉलम जोड़ते समय, उन्हें अलग-अलग अलर्ट स्टेटमेंट में जोड़ें ताकि एक डुप्लिकेट दूसरों को बनने से न रोके।

साथ SQLite शुद्ध है, हम कुछ इस तरह से किया था। यह सही नहीं है, क्योंकि हम डुप्लिकेट साइक्लिट त्रुटियों को अन्य साइक्लाइट त्रुटियों से अलग नहीं कर सकते हैं।

Dictionary<string, string> columnNameToAddColumnSql = new Dictionary<string, string>
{
    {
        "Column1",
        "ALTER TABLE MyTable ADD COLUMN Column1 INTEGER"
    },
    {
        "Column2",
        "ALTER TABLE MyTable ADD COLUMN Column2 TEXT"
    }
};

foreach (var pair in columnNameToAddColumnSql)
{
    string columnName = pair.Key;
    string sql = pair.Value;

    try
    {
        this.DB.ExecuteNonQuery(sql);
    }
    catch (System.Data.SQLite.SQLiteException e)
    {
        _log.Warn(e, string.Format("Failed to create column [{0}]. Most likely it already exists, which is fine.", columnName));
    }
}

28

SQLite "टेबल_इनफो" नामक एक प्रैग्मेंट स्टेटमेंट का भी समर्थन करता है जो कॉलम के नाम (और कॉलम के बारे में अन्य जानकारी) के साथ तालिका में प्रति कॉलम एक पंक्ति देता है। आप अनुपलब्ध स्तंभ की जाँच करने के लिए क्वेरी में इसका उपयोग कर सकते हैं, और यदि तालिका में परिवर्तन नहीं किया गया है।

PRAGMA table_info(foo_table_name)

http://www.sqlite.org/pragma.html#pragma_table_info


30
आपका उत्तर बहुत अधिक उत्कृष्ट होगा कि आप केवल एक लिंक के बजाय उस खोज को पूरा करने के लिए कोड प्रदान करें।
माइकल एलन हफ़

PRAGMA table_info (table_name)। यह कमांड परिणाम में एक पंक्ति के रूप में table_name के प्रत्येक कॉलम को सूचीबद्ध करेगा। इस परिणाम के आधार पर, आप यह निर्धारित कर सकते हैं कि कॉलम मौजूद था या नहीं।
हाओ गुयेन

2
क्या किसी बड़े SQL स्टेटमेंट के हिस्से में प्रैग्म को जोड़कर ऐसा करने का कोई तरीका है जैसे कि कॉलम को जोड़ा जाता है यदि यह मौजूद नहीं है लेकिन अन्यथा, केवल एक क्वेरी में नहीं है?
माइकल

1
@Michael। जहाँ तक मुझे पता है, नहीं, तुम नहीं कर सकते। PRAGMA कमांड के साथ समस्या यह है कि आप इस पर क्वेरी नहीं कर सकते। कमांड एसक्यूएल इंजन के लिए डेटा प्रस्तुत नहीं करता है, यह सीधे परिणाम देता है
कोवलन

1
क्या यह एक दौड़ की स्थिति नहीं बनाता है? मान लें कि मैं कॉलम के नामों की जाँच करता हूं, यह देखें कि मेरा कॉलम गायब है, लेकिन इस बीच एक और प्रक्रिया कॉलम को जोड़ती है। फिर मैं कॉलम को जोड़ने का प्रयास करूंगा लेकिन एक त्रुटि मिलेगी क्योंकि यह पहले से मौजूद है। मुझे लगता है कि मैं पहले या कुछ डेटाबेस को बंद करने वाला हूं? मैं साइक्लाइट के लिए एक noob हूं मैं डरता हूं :)।
बेन किसान

25

यदि आप DB अपग्रेड स्टेटमेंट में ऐसा कर रहे हैं, तो शायद सबसे आसान तरीका यह है कि यदि आप पहले से मौजूद किसी क्षेत्र को जोड़ने का प्रयास कर रहे हैं, तो आप केवल उस अपवाद को पकड़ सकते हैं।

try {
   db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN foo TEXT default null");
} catch (SQLiteException ex) {
   Log.w(TAG, "Altering " + TABLE_NAME + ": " + ex.getMessage());
}

2
मुझे अपवाद-शैली की प्रोग्रामिंग पसंद नहीं है, लेकिन यह आश्चर्यजनक रूप से साफ है। हो सकता है कि आपने मुझे थोडा हिला दिया हो।
स्टीफन जे

मुझे यह पसंद नहीं है, लेकिन C ++ अब तक की सबसे अपवाद शैली की प्रोग्रामिंग भाषा है। इसलिए मुझे लगता है कि कोई भी इसे "वैध" के रूप में देख सकता है।
tmighty

SQLite के लिए मेरा उपयोग मामला = मैं अन्य भाषाओं (MSSQL) में कुछ सरल / एक लाइनर के लिए एक टन अतिरिक्त कोडिंग नहीं करना चाहता। अच्छा जवाब ... हालांकि यह "अपग्रेड स्टाइल स्टाइल प्रोग्रामिंग" है, यह एक अपग्रेड फंक्शन / अलग-थलग है इसलिए मुझे लगता है कि यह स्वीकार्य है।
maplemale

जबकि अन्य इसे पसंद नहीं करते हैं, मुझे लगता है कि यह सबसे अच्छा समाधान है
एडम वराहिजी

13

सिंहासन PRAGMA का एक तरीका है table_info (table_name), यह तालिका की सभी जानकारी लौटाता है।

यह लागू है कि चेक कॉलम के लिए इसका उपयोग कैसे किया जाए या नहीं,

    public boolean isColumnExists (String table, String column) {
         boolean isExists = false
         Cursor cursor;
         try {           
            cursor = db.rawQuery("PRAGMA table_info("+ table +")", null);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    String name = cursor.getString(cursor.getColumnIndex("name"));
                    if (column.equalsIgnoreCase(name)) {
                        isExists = true;
                        break;
                    }
                }
            }

         } finally {
            if (cursor != null && !cursor.isClose()) 
               cursor.close();
         }
         return isExists;
    }

आप लूप का उपयोग किए बिना भी इस क्वेरी का उपयोग कर सकते हैं,

cursor = db.rawQuery("PRAGMA table_info("+ table +") where name = " + column, null);

कर्सर कर्सर = db.rawQuery ("तालिका नाम से चयन करें", अशक्त); कॉलम = कर्सर.getColumnNames ();
वाह ग़रीबन

1
मुझे लगता है कि आप कर्सर को बंद करना भूल गए :-)
पेकाना

@VaheGharibyan, तो आप बस कॉलम नाम पाने के लिए अपने DB में सब कुछ का चयन करेंगे? आप जो कह रहे हैं वह है we give no shit about performance:))।
फरीद

ध्यान दें, अंतिम क्वेरी गलत है। उचित प्रश्न यह है: SELECT * FROM pragma_table_info(...)(ध्यान और तालिका जानकारी के बीच चयन और अंडरस्कोर नोट करें)। यह निश्चित नहीं है कि वास्तव में उन्होंने इसे किस संस्करण में जोड़ा है, यह 3.16.0 पर काम नहीं करता था, लेकिन यह 3.22.0 पर काम करता है।
प्रेसिंगऑनवेवेज

3

उन लोगों के लिए pragma table_info()एक बड़े SQL के हिस्से के रूप में परिणाम का उपयोग करना चाहते हैं ।

select count(*) from
pragma_table_info('<table_name>')
where name='<column_name>';

इसके pragma_table_info('<table_name>')बजाय मुख्य भाग का उपयोग करना है pragma table_info('<table_name>')


यह उत्तर @Robert Hawkey के उत्तर से प्रेरित है। मैं इसे एक नए उत्तर के रूप में पोस्ट करने का कारण यह है कि टिप्पणी के रूप में इसे पोस्ट करने के लिए मेरे पास पर्याप्त प्रतिष्ठा नहीं है।


1

मैं इस प्रश्न के साथ आता हूं

SELECT CASE (SELECT count(*) FROM pragma_table_info(''product'') c WHERE c.name = ''purchaseCopy'') WHEN 0 THEN ALTER TABLE product ADD purchaseCopy BLOB END
  • यदि कॉलम मौजूद है, तो आंतरिक क्वेरी 0 या 1 पर वापस आ जाएगी।
  • परिणाम के आधार पर, कॉलम को बदलें

कोड = त्रुटि (1), संदेश = System.Data.SQLite.SQLiteException (0x800007BF): SQL तर्क त्रुटि "ALTER" के पास: System.Data.SQLite.SQLite3.Prepare पर वाक्यविन्यास त्रुटि
イ ン

0

यदि आप फ्लेक्स / एडोब हवा में इस समस्या से जूझ रहे हैं और पहले खुद को यहां देखें, मैंने एक समाधान ढूंढ लिया है, और इसे संबंधित प्रश्न पर पोस्ट किया है: ADD COLUMN to sqlite db IF NOT EXISTS - flex / air sqlite?

मेरी टिप्पणी यहाँ: https://stackoverflow.com/a/24928437/2678219


0

मैंने इसका उत्तर C # /। नेट में लिया है, और इसे Qt / C ++ के लिए फिर से लिखा है, बहुत अधिक नहीं बदला है, लेकिन मैं भविष्य में इसे C ++ 'ish' उत्तर की तलाश में किसी के लिए भी छोड़ना चाहता था।

    bool MainWindow::isColumnExisting(QString &table, QString &columnName){

    QSqlQuery q;

    try {
        if(q.exec("PRAGMA table_info("+ table +")"))
            while (q.next()) {
                QString name = q.value("name").toString();     
                if (columnName.toLower() == name.toLower())
                    return true;
            }

    } catch(exception){
        return false;
    }
    return false;
}

0

यदि आप कॉलम मौजूद हैं, तो यह जानने के लिए कि आप pragma_table_info के साथ संयोजन में CASE-WHEN TSQL स्टेटमेंट का वैकल्पिक रूप से उपयोग कर सकते हैं:

select case(CNT) 
    WHEN 0 then printf('not found')
    WHEN 1 then printf('found')
    END
FROM (SELECT COUNT(*) AS CNT FROM pragma_table_info('myTableName') WHERE name='columnToCheck') 

यहाँ हम टेबल कैसे बदलते हैं? स्तंभ नाम मिलान कब है?
user2700767 14

0

यहाँ मेरा समाधान है, लेकिन अजगर में (मैंने अजगर से संबंधित विषय पर कोई भी पोस्ट खोजने की कोशिश की और असफल रहा):

# modify table for legacy version which did not have leave type and leave time columns of rings3 table.
sql = 'PRAGMA table_info(rings3)' # get table info. returns an array of columns.
result = inquire (sql) # call homemade function to execute the inquiry
if len(result)<= 6: # if there are not enough columns add the leave type and leave time columns
    sql = 'ALTER table rings3 ADD COLUMN leave_type varchar'
    commit(sql) # call homemade function to execute sql
    sql = 'ALTER table rings3 ADD COLUMN leave_time varchar'
    commit(sql)

मैंने तालिका जानकारी प्राप्त करने के लिए PRAGMA का उपयोग किया। यह कॉलम के बारे में जानकारी से भरा एक बहुआयामी सरणी देता है - प्रति कॉलम एक सरणी। मैं स्तंभों की संख्या प्राप्त करने के लिए सरणियों की संख्या गिनता हूं। यदि पर्याप्त कॉलम नहीं हैं, तो मैं ALTER TABLE कमांड का उपयोग करके कॉलम जोड़ता हूं।


0

यदि आप एक समय में एक पंक्ति निष्पादित करते हैं तो ये सभी उत्तर ठीक हैं। हालांकि, मूल प्रश्न एक एसक्यूएल स्क्रिप्ट को इनपुट करने के लिए था जिसे एक एकल डीबी निष्पादित द्वारा निष्पादित किया जाएगा और सभी समाधान (जैसे यह देखने के लिए जांचना कि स्तंभ समय से पहले है) को निष्पादन कार्यक्रम की आवश्यकता होगी या तो तालिकाओं का ज्ञान होगा इस जानकारी को निर्धारित करने के लिए कॉलम को बदल दिया / जोड़ा जा रहा है या इनपुट स्क्रिप्ट की पूर्व-प्रसंस्करण और पार्सिंग कर रहे हैं। आमतौर पर आप इसे रीयलटाइम या अक्सर चलाने नहीं जा रहे हैं। तो एक अपवाद को पकड़ने का विचार स्वीकार्य है और फिर आगे बढ़ रहा है। उसमें समस्या है ... कैसे आगे बढ़ना है। सौभाग्य से त्रुटि संदेश हमें यह करने के लिए आवश्यक सभी जानकारी देता है। यदि यह परिवर्तन तालिका कॉल पर अपवाद करता है, तो हम sql को निष्पादित करने के लिए विचार कर सकते हैं, हम sql में परिवर्तन तालिका लाइन को ढूंढ सकते हैं और शेष पंक्तियों को वापस कर सकते हैं और तब तक निष्पादित कर सकते हैं जब तक कि या तो अधिक मेल खाती हुई परिवर्तन तालिका रेखाएं नहीं मिल सकती हैं। कुछ उदाहरण कोड का उपयोग करता है जहां हमारे पास एक सरणी में sql स्क्रिप्ट है। हम प्रत्येक स्क्रिप्ट को निष्पादित करने वाले सरणी को पुनरावृत्त करते हैं। हम इसे दो बार कॉल करते हैं कि परिवर्तन तालिका कमांड को विफल करने के लिए लेकिन कार्यक्रम सफल होता है क्योंकि हम sql से परिवर्तन तालिका कमांड को हटा देते हैं और अद्यतन कोड को फिर से निष्पादित करते हैं।

#!/bin/sh
# the next line restarts using wish \

exec /opt/usr8.6.3/bin/tclsh8.6  "$0" ${1+"$@"}
foreach pkg {sqlite3 } {
    if { [ catch {package require {*}$pkg } err ] != 0 } {
    puts stderr "Unable to find package $pkg\n$err\n ... adjust your auto_path!";
    }
}
array set sqlArray {
    1 {
    CREATE TABLE IF NOT EXISTS Notes (
                      id INTEGER PRIMARY KEY AUTOINCREMENT,
                      name text,
                      note text,
                      createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                      updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
                      );
    CREATE TABLE IF NOT EXISTS Version (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        version text,
                        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
                        );
    INSERT INTO Version(version) values('1.0');
    }
    2 {
    CREATE TABLE IF NOT EXISTS Tags (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name text,
        tag text,
        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
        );
    ALTER TABLE Notes ADD COLUMN dump text;
    INSERT INTO Version(version) values('2.0');
    }
    3 {
    ALTER TABLE Version ADD COLUMN sql text;
    INSERT INTO Version(version) values('3.0');
    }
}

# create db command , use in memory database for demonstration purposes
sqlite3 db :memory:

proc createSchema { sqlArray } {
    upvar $sqlArray sql
    # execute each sql script in order 
    foreach version [lsort -integer [array names sql ] ] {
    set cmd $sql($version)
    set ok 0
    while { !$ok && [string length $cmd ] } {  
        try {
        db eval $cmd
        set ok 1  ;   # it succeeded if we get here
        } on error { err backtrace } {
        if { [regexp {duplicate column name: ([a-zA-Z0-9])} [string trim $err ] match columnname ] } {
            puts "Error:  $err ... trying again" 
            set cmd [removeAlterTable $cmd $columnname ]
        } else {
            throw DBERROR "$err\n$backtrace"
        }
        }
    }
    }
}
# return sqltext with alter table command with column name removed
# if no matching alter table line found or result is no lines then
# returns ""
proc removeAlterTable { sqltext columnname } {
    set mode skip
    set result [list]
    foreach line [split $sqltext \n ] {
    if { [string first "alter table" [string tolower [string trim $line] ] ] >= 0 } {
        if { [string first $columnname $line ] } {
        set mode add
        continue;
        }
    }
    if { $mode eq "add" } {
        lappend result $line
    }
    }
    if { $mode eq "skip" } {
    puts stderr "Unable to find matching alter table line"
    return ""
    } elseif { [llength $result ] }  { 
    return [ join $result \n ]
    } else {
    return ""
    }
}
               
proc printSchema { } {
    db eval { select * from sqlite_master } x {
    puts "Table: $x(tbl_name)"
    puts "$x(sql)"
    puts "-------------"
    }
}
createSchema sqlArray
printSchema
# run again to see if we get alter table errors 
createSchema sqlArray
printSchema

अपेक्षित उत्पादन

Table: Notes
CREATE TABLE Notes (
                      id INTEGER PRIMARY KEY AUTOINCREMENT,
                      name text,
                      note text,
                      createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                      updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
                      , dump text)
-------------
Table: sqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
-------------
Table: Version
CREATE TABLE Version (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        version text,
                        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
                        , sql text)
-------------
Table: Tags
CREATE TABLE Tags (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name text,
        tag text,
        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
        )
-------------
Error:  duplicate column name: dump ... trying again
Error:  duplicate column name: sql ... trying again
Table: Notes
CREATE TABLE Notes (
                      id INTEGER PRIMARY KEY AUTOINCREMENT,
                      name text,
                      note text,
                      createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                      updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
                      , dump text)
-------------
Table: sqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)
-------------
Table: Version
CREATE TABLE Version (
                        id INTEGER PRIMARY KEY AUTOINCREMENT,
                        version text,
                        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
                        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) )
                        , sql text)
-------------
Table: Tags
CREATE TABLE Tags (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name text,
        tag text,
        createdDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) ,
        updatedDate integer(4) DEFAULT ( cast( strftime('%s', 'now') as int ) ) 
        )
-------------

0
select * from sqlite_master where type = 'table' and tbl_name = 'TableName' and sql like '%ColumnName%'

तर्क: sqlite_master में sql कॉलम में टेबल की परिभाषा होती है, इसलिए इसमें निश्चित रूप से कॉलम नाम के साथ स्ट्रिंग होती है।

जैसा कि आप एक उप-स्ट्रिंग की खोज कर रहे हैं, इसकी स्पष्ट सीमाएं हैं। इसलिए मैं ColumnName में और भी अधिक प्रतिबंधात्मक उप-स्ट्रिंग का उपयोग करने का सुझाव दूंगा, उदाहरण के लिए कुछ इस तरह ('' वर्ण के रूप में परीक्षण के अधीन) हमेशा नहीं होता है]

select * from sqlite_master where type = 'table' and tbl_name = 'MyTable' and sql like '%`MyColumn` TEXT%'

0

मैं इसे 2 प्रश्नों में हल करता हूं। यह System.Data.SQLite का उपयोग करके मेरी यूनिटी 3 डी स्क्रिप्ट है।

IDbCommand command = dbConnection.CreateCommand();
            command.CommandText = @"SELECT count(*) FROM pragma_table_info('Candidat') c WHERE c.name = 'BirthPlace'";
            IDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                try
                {
                    if (int.TryParse(reader[0].ToString(), out int result))
                    {
                        if (result == 0)
                        {
                            command = dbConnection.CreateCommand();
                            command.CommandText = @"ALTER TABLE Candidat ADD COLUMN BirthPlace VARCHAR";
                            command.ExecuteNonQuery();
                            command.Dispose();
                        }
                    }
                }
                catch { throw; }
            }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.