मैं SQLite में कैसे जाँच करूँ कि क्या कोई तालिका मौजूद है?


893

मैं कैसे, मज़बूती से , SQLite में जाँच, क्या एक विशेष उपयोगकर्ता तालिका मौजूद है?

मैं जाँच करने जैसे अविश्वसनीय तरीके नहीं पूछ रहा हूँ कि क्या मेज पर "चयन *" से कोई त्रुटि हुई है या नहीं (क्या यह एक अच्छा विचार है?)।

कारण इस प्रकार है:

मेरे कार्यक्रम में, मुझे पहले से मौजूद नहीं होने पर कुछ तालिकाओं को बनाने और फिर से पॉप्युलेट करने की आवश्यकता है।

यदि वे पहले से मौजूद हैं, तो मुझे कुछ तालिकाओं को अपडेट करने की आवश्यकता है।

क्या मुझे यह संकेत देने के बजाय कुछ और रास्ता निकालना चाहिए कि प्रश्न में तालिकाएँ पहले ही बनाई गई हैं - उदाहरण के लिए, अपने प्रोग्राम इनिशियलाइज़ेशन / सेटिंग्स फ़ाइल में डिस्क या कुछ पर एक निश्चित ध्वज बनाने / डाल / सेट करके?

या मेरा दृष्टिकोण समझ में आता है?


यदि चयन में तालिका मौजूद नहीं है, तो SQLite एक अपवाद फेंक देगा। बस किसी और फैंसी काम की जरूरत नहीं है।
NoChance

34
@ कोई बात नहीं, लेकिन यह अन्य चीजों की संख्या होगी। यह देखने में थोड़ा सा है कि क्या वह पेड़ वास्तव में आपकी आंखों के साथ आगे की ओर ड्राइविंग करके है, तो आपको एक रास्ता या दूसरा पता चल जाएगा :)
randomsock

@randomsock, अच्छा उदाहरण है, लेकिन थोड़ा डरावना है, खासकर अगर कार मेरी कार थी ...
NoChance

@randomsock, मुझे नहीं पता कि साइक्लाइट सम्मेलन क्या है, लेकिन अनुमति से माफी मांगने के लिए यह अधिक पायथोनिक है। सशर्त का उपयोग करने के बजाय अपवाद को पकड़ें।
एरिक

1
@ अब तक, इस प्रश्न में पायथन शामिल नहीं है, लेकिन यह मानते हुए कि त्रुटि एक सामान्य है sqlite3.OperationalError, इसलिए आपको यह सुनिश्चित करने के लिए त्रुटि संदेश को पार्स करना होगा कि यह बनाते समय "तालिका TABLE_NAME पहले से मौजूद है" संदेश। एक तालिका, और यदि नहीं, तो त्रुटि को सुधारें और मुझे लगता है कि इस बात की कोई गारंटी नहीं है कि त्रुटि को बदलने की आवश्यकता नहीं होगी।
मार्कस वॉन ब्रॉडी

जवाबों:


1019

मुझे वह FAQ प्रविष्टि याद आती है।

वैसे भी, भविष्य के संदर्भ के लिए, पूरी क्वेरी है:

SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';

{table_name}जाँच करने के लिए तालिका का नाम कहाँ है।

संदर्भ के लिए दस्तावेज़ीकरण अनुभाग: डेटाबेस फ़ाइल प्रारूप। 2.6। SQL डेटाबेस स्कीमा का संग्रहण

  • यह निर्दिष्ट नाम के साथ तालिकाओं की एक सूची लौटाएगा; अर्थात्, कर्सर में 0 की गिनती (मौजूद नहीं है) या 1 की गिनती होगी (मौजूद है)

7
SQLite प्रलेखन में से कौन सा सिस्टम टेबल को कवर करता है?
पावेल वेसलोव

29
@Pelel Veselov: "फ़ाइल स्वरूप SQLite डेटाबेस के लिए" शीर्षक: sqlite.org/fileformat2.html
ब्रायन ओकले

14
हालाँकि, यह TEMP तालिकाओं के लिए काम नहीं करेगा। TEMP टेबल "sqlite_temp_master" में हैं।
पचफॉग

11
क्या यह एक बूलियन लौटाता है? यदि टेबल करता है या मौजूद नहीं है तो यह क्या लौटाता है?
Dagrooms

8
@ डैगरूम यह निर्दिष्ट नाम के साथ तालिकाओं की एक सूची लौटाएगा; अर्थात्, कर्सर में 0 की संख्या (मौजूद नहीं है) या 1 की गिनती (मौजूद है) होगी।
रीन एस

555

यदि आप SQLite संस्करण 3.3+ का उपयोग कर रहे हैं, तो आप आसानी से एक तालिका बना सकते हैं:

create table if not exists TableName (col1 typ1, ..., colN typN)

उसी तरह, आप किसी तालिका को केवल तभी निकाल सकते हैं जब वह मौजूद हो:

drop table if exists TableName

3
ध्यान दें कि create tableकथन अधूरा है (तालिका कॉलम विनिर्देश को याद कर रहा है)।
एरिक प्लैटन

11
इंडेक्स के लिए भी इसी तरह का निर्माण है:
टेबलनेट

26
यह स्वीकृत उत्तर नहीं होना चाहिए, लेकिन यदि प्रश्न अलग-अलग शब्दों में लिखा गया हो। ओपी ने यह नहीं पूछा कि ड्रॉप करने या बनाने से पहले टेबल की जांच कैसे की जाए। क्या होगा यदि आपको एक तालिका को क्वेरी करना है जो संभवतः मौजूद नहीं है? यह वह समस्या है जिसका मैं अभी सामना कर रहा हूं, और स्वीकृत उत्तर इस सामान्य समस्या कथन में सबसे अच्छा काम करता है। यह एक अच्छा त्वरित विकल्प है।
Dagrooms

@ डैगरूम, आप सही हो सकते हैं। हालाँकि ओपी ने यह नहीं पूछा, मैं इस उत्तर की तलाश कर रहा था :)
ईरिक87

169

भिन्नता का चयन SELAME NAME के ​​बजाय SELECT COUNT (*) का उपयोग करने के लिए किया जाएगा

SELECT count(*) FROM sqlite_master WHERE type='table' AND name='table_name';

यदि तालिका मौजूद नहीं है, तो यह 0 होगा, यदि यह होता है। यह संभवतः आपके प्रोग्रामिंग में उपयोगी है क्योंकि एक संख्यात्मक परिणाम प्रक्रिया के लिए तेज / आसान है। निम्न दिखाता है कि आप मापदंडों के साथ SQLiteDatabase, Cursor, rawQuery का उपयोग करके Android में यह कैसे करेंगे।

boolean tableExists(SQLiteDatabase db, String tableName)
{
    if (tableName == null || db == null || !db.isOpen())
    {
        return false;
    }
    Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?", new String[] {"table", tableName});
    if (!cursor.moveToFirst())
    {
        cursor.close();
        return false;
    }
    int count = cursor.getInt(0);
    cursor.close();
    return count > 0;
}

33
मेरा मानना ​​है कि "SELECT 1" और भी तेज होगा।
पैचफॉग

क्यों डेटाबेस में रिकॉर्ड्स की गणना करने के लिए कर्सर.गेटइंट (0) बराबर है?
शमौन दानिलोव

1
हम उस समय की संख्या की गिनती कर रहे हैं जब टेबल साइक्लाइट स्कीमा में दिखाई देती है। 0 की गणना का अर्थ है तालिका मौजूद नहीं है। 1 की गिनती का अर्थ है तालिका मौजूद है। ये गिनती के केवल दो अपेक्षित मूल्य हैं।
स्टीफन क्वान

1
जबकि संख्या (से COUNT(*)) प्रक्रिया करना आसान है, किसी पंक्ति के अस्तित्व को वापस करना आसान है या नहीं; अगर वहाँ एक पंक्ति है तो यह मौजूद है, अगर वहाँ कोई पंक्ति नहीं है। (आप पहले से ही MoveToFirst में विफलता की जांच करते हैं, इसलिए उस बिंदु पर काम किया जाएगा।)
डैश-टॉम-बैंग

झूठे वापस आने से पहले कर्सर को बंद करने के लिए कृपया अपना कोड अपडेट करें।
डेव थॉमस

43

तुम कोशिश कर सकते हो:

SELECT name FROM sqlite_master WHERE name='table_name'

4
प्रकार = तालिका उपयोगी
थान

यदि C # का उपयोग कर रहे हैं, तो इस कमांड का उपयोग न करें SQLiteReader reader = cmd.ExecuteReader();और dt.Load(reader)( a (जहाँ dta DataTable) करें। मैंने पाया Object reference is not an instance of an objectकि .Load()यदि तालिका नहीं मिली है तो यह अपवाद देता है। इसके बजाय, एक का उपयोग करें SQLiteDataAdapter adapter = new SQLiteDataAdapter(cmd); और करते हैं adapter.Fill(ds), जहां dsएक है DataSet। आप तब देख सकते हैं कि क्या ds.Tables.Count > 0और return ds.Tables[0];यदि ऐसा है (या else return null)। तब आप जाँच सकते हैं कि DataTableहोने के लिए null, अगर dt.Rows != null, और अगरdt.Rows.Count>0
vapcguy 22

34

उपयोग:

PRAGMA table_info(your_table_name)

यदि परिणामी तालिका खाली है तो your_table_nameअस्तित्व में नहीं है।

प्रलेखन:

PRAGMA स्कीमा.table_info (तालिका-नाम);

यह प्रस्तावित नाम तालिका में प्रत्येक स्तंभ के लिए एक पंक्ति देता है। परिणाम सेट में कॉलम में कॉलम का नाम, डेटा प्रकार, कॉलम NULL हो सकता है या नहीं, और कॉलम के लिए डिफ़ॉल्ट मान शामिल है। परिणाम सेट में "pk" कॉलम उन स्तंभों के लिए शून्य है जो प्राथमिक कुंजी का हिस्सा नहीं हैं, और प्राथमिक कुंजी के भाग वाले स्तंभों के लिए प्राथमिक कुंजी में स्तंभ का सूचकांक है।

Table_info प्राग्मा में नामित तालिका भी एक दृश्य हो सकती है।

उदाहरण आउटपुट:

cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0

यह निर्धारित करने का एक शानदार तरीका है कि पायथन में एक तालिका मौजूद है या नहीं।
माइकल मर्फी

या Xamarin प्रपत्र
SerenityNow

4
यह एक शानदार तरीका है स्तंभ परिभाषाओं पर प्रोग्रामेटिक रूप से प्राप्त करने के लिए
w00t

33

SQLite तालिका नाम केस असंवेदनशील हैं, लेकिन तुलना डिफ़ॉल्ट रूप से संवेदनशील है। इस काम को सही तरीके से करने के लिए आपको उन सभी मामलों को जोड़ना होगा COLLATE NOCASE

SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE

33

यदि आपको "तालिका पहले से मौजूद है" त्रुटि मिल रही है, तो नीचे दिए अनुसार SQL स्ट्रिंग में परिवर्तन करें:

CREATE table IF NOT EXISTS table_name (para1,para2);

इस तरह आप अपवादों से बच सकते हैं।



23

यदि आप fmdb का उपयोग कर रहे हैं , तो मुझे लगता है कि आप बस FMDatabaseAdditions आयात कर सकते हैं और बूल फ़ंक्शन का उपयोग कर सकते हैं :

[yourfmdbDatabase tableExists:tableName].

1
सुनिश्चित करें कि आप इस विधि का उपयोग करने के लिए "FMDatabaseAdditions.h" आयात करते हैं या फिर आपको आश्चर्य होगा कि उन्होंने इसे क्यों निकाला! :)
विल

हालाँकि यह एक सही उत्तर हो सकता है, लेकिन सवाल यह था कि एक विशेष भाषा में एक विशेष पुस्तकालय के लिए साइक्लाइट नहीं था। मुझे लगता है कि इसका जवाब एसक्यूएल कोड प्रदान करना चाहिए, न कि पुस्तकालय के तरीकों में से एक के लिए कॉल
nacho4d

13

निम्न तालिका 1 मौजूद है यदि तालिका मौजूद है या 0 यदि तालिका मौजूद नहीं है।

SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"

1
यह तब भी कुछ भी नहीं लौटाएगा यदि तालिका मौजूद नहीं है, क्योंकि जहां स्थिति किसी भी परिणाम को रोकती है।
डेविड गौस्मान

10

ध्यान दें कि TEMP डेटाबेस में कोई तालिका मौजूद है या नहीं, यह जाँचने के लिए, आपको sqlite_temp_masterइसके बजाय उपयोग करना होगा sqlite_master:

SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';

9

यहां वह फ़ंक्शन है जो मैंने उपयोग किया था:

SQLDatabase Object = db दिया गया है

public boolean exists(String table) {
    try {
         db.query("SELECT * FROM " + table);
         return true;
    } catch (SQLException e) {
         return false;
    }
}

1
मुझे दुख की बात है कि मुझे अपने एंड्रॉइड ऐप में इसका उपयोग करना पड़ा क्योंकि मैंने पाया कि सैमसंग डिवाइस मानक sqlite_master टेबल संरचना का उपयोग नहीं करते हैं जो बाकी सभी के साथ काम कर रहे हैं।
एंथनी चुइनार्ड

7

इस कोड का उपयोग करें:

SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';

अगर लौटी हुई सरणी गिनती 1 के बराबर है तो इसका मतलब है कि तालिका मौजूद है। अन्यथा यह मौजूद नहीं है।


4
class CPhoenixDatabase():
    def __init__(self, dbname):
        self.dbname = dbname
        self.conn = sqlite3.connect(dbname)

    def is_table(self, table_name):
        """ This method seems to be working now"""
        query = "SELECT name from sqlite_master WHERE type='table' AND name='{" + table_name + "}';"
        cursor = self.conn.execute(query)
        result = cursor.fetchone()
        if result == None:
            return False
        else:
            return True

नोट: यह मेरे मैक पर अब पायथन 3.7.1 के साथ काम कर रहा है


यह अन्य सभी उत्तरों की तुलना में अधिक साफ दिखता है .. धन्यवाद !!
हर्षवर्धन

मेरे लिए काम नहीं करता है: table_name के आसपास {} कोष्ठक को मिटाना पड़ता है, फिर उसका जुर्माना।
केले

1
सुनिश्चित करें कि table_nameअप्रयुक्त स्रोत (जैसे उपयोगकर्ता इनपुट) से प्रदान नहीं किया गया है, अन्यथा यह SQL इंजेक्शन के लिए असुरक्षित होगा। पाठ हेरफेर तकनीकों के बजाय मापदंडों का उपयोग करना हमेशा बेहतर होता है
एस्टीफ़ ऑर्ग

3

उपयोग

SELECT 1 FROM table LIMIT 1;

सभी रिकॉर्ड्स को पढ़ने से रोकने के लिए।


यदि तालिका मौजूद है तो यह NULL लौटाती है लेकिन कोई रिकॉर्ड नहीं है।
रेडियोसपील

यदि तालिका मौजूद नहीं है, तो यह एक त्रुटि फेंक देगा। पकड़ो, और तुम्हें पता है कि यह मौजूद नहीं है।
भाग्योदयवाद

प्रवाह नियंत्रण के रूप में त्रुटि से निपटने का उपयोग करना आमतौर पर सबसे अच्छा अभ्यास नहीं माना जाता है। इससे शायद बचना चाहिए।
जेफ वुडार्ड

3

तालिका अस्तित्व की जाँच करने के लिए आप निम्नलिखित प्रश्न लिख सकते हैं।

SELECT name FROM sqlite_master WHERE name='table_name'

यहाँ 'table_name' आपकी तालिका का नाम है जिसे आपने बनाया है। उदाहरण के लिए

 CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"

और जाँच करें

  SELECT name FROM sqlite_master WHERE name='country'

6
यह 9 साल पहले से पहले से स्वीकार किए गए टॉपवोट उत्तर से कैसे अलग है?
केविन वान डाइक

3

नवीनतम सीक्लाइट-नेट-पल्क नगेट पैकेज (1.5.231) जो कि SQLite 3 का उपयोग कर रहा है, का उपयोग करते हुए मैंने अभी तक सबसे विश्वसनीय तरीका C # में पाया है, इस प्रकार है:

var result = database.GetTableInfo(tableName);
if ((result == null) || (result.Count == 0))
{
    database.CreateTable<T>(CreateFlags.AllImplicit);
}

2

एक सरल चयन क्वेरी का उपयोग करना - मेरी राय में - काफी विश्वसनीय है। सबसे अधिक यह कई अलग-अलग डेटाबेस प्रकारों में तालिका अस्तित्व की जांच कर सकता है (SQLite / MySQL)।

SELECT 1 FROM table;

यह तब समझ में आता है जब आप यह निर्धारित करने के लिए अन्य विश्वसनीय तंत्र का उपयोग कर सकते हैं कि क्या क्वेरी सफल हुई (उदाहरण के लिए, आप Qt में QSqlQuery के माध्यम से एक डेटाबेस क्वेरी करते हैं )।


1

c ++ फ़ंक्शन तालिका की मौजूदगी और (वैकल्पिक रूप से) कॉलम के लिए db और सभी संलग्न डेटाबेस की जाँच करता है।

bool exists(sqlite3 *db, string tbl, string col="1")
{
    sqlite3_stmt *stmt;
    bool b = sqlite3_prepare_v2(db, ("select "+col+" from "+tbl).c_str(),
    -1, &stmt, 0) == SQLITE_OK;
    sqlite3_finalize(stmt);
    return b;
}

संपादित करें: हाल ही में sqlite3_table_column_metadata फ़ंक्शन की खोज की गई। इसलिये

bool exists(sqlite3* db,const char *tbl,const char *col=0)
{return sqlite3_table_column_metadata(db,0,tbl,col,0,0,0,0,0)==SQLITE_OK;}

सार्वजनिक स्थैतिक बूलियन tableExists (SQLiteDatabase डेटाबेस, स्ट्रिंग tableName) {वापसी database.rawQuery ("से एक नाम चुनें sqlite_master जहाँ टाइप करें '=' ​​तालिका 'और नाम =" + tableName + +' ", null) .moveToFirst (); }
निक

बहुत ही अकुशल और जोखिम भरा तरीका है क्योंकि स्ट्रिंग संघनन से सब कुछ खत्म हो सकता है।
एंड्रिया मोरो

0

यह SQLite कॉर्डोवा के लिए मेरा कोड है:

get_columnNames('LastUpdate', function (data) {
    if (data.length > 0) { // In data you also have columnNames
        console.log("Table full");
    }
    else {
        console.log("Table empty");
    }
});

और दूसरा जो है:

function get_columnNames(tableName, callback) {
    myDb.transaction(function (transaction) {
        var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'";
        transaction.executeSql(query_exec, [], function (tx, results) {
            var columnNames = [];
            var len = results.rows.length;
            if (len>0){
                var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx
                for (i in columnParts) {
                    if (typeof columnParts[i] === 'string')
                        columnNames.push(columnParts[i].split(" ")[0]);
                };
                callback(columnNames);
            }
            else callback(columnNames);
        });
    });
}

0

मैंने सोचा कि मैं इस चर्चा में अपने 2 सेंट लगा दूं, भले ही यह एक पुराना हो। यह क्वेरी स्केलर 1 रिटर्न करती है यदि तालिका मौजूद है और अन्यथा।

select 
    case when exists 
        (select 1 from sqlite_master WHERE type='table' and name = 'your_table') 
        then 1 
        else 0 
    end as TableExists

0

तालिका स्विफ्ट में डेटाबेस में मौजूद है या नहीं

func tableExists(_ tableName:String) -> Bool {
        sqlStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='\(tableName)'"
        if sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, nil) == SQLITE_OK {
            if sqlite3_step(compiledStatement) == SQLITE_ROW {
                return true
            }
            else {
                return false
            }
        }
        else {
            return false
        }
            sqlite3_finalize(compiledStatement)
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.