Verificați dacă o coloană există în SQLite (Programare, Sqlite)

Herrozerro a intrebat.

Am nevoie să verific dacă o coloană există și dacă nu există să o adaug. Din cercetările mele se pare că sqlite nu acceptă declarații IF și ar trebui folosită în schimb declarația case.

Iată ce am până acum:

SELECT CASE WHEN exists(select * from qaqc.columns where Name = "arg" and Object_ID = Object_ID("QAQC_Tasks")) = 0 THEN ALTER TABLE QAQC_Tasks ADD arg INT DEFAULT(0);

Dar primesc eroarea: Near „ALTER”: Eroare de sintaxă.

Aveți vreo idee?

Comentarii

  • Dacă utilizați API C/C++, verificați sqlite3_table_column_metadata() function. Aceasta returnează SQLITE_OK dacă coloana există și SQLITE_ERROR dacă nu există. –  > Por Mar.
  • Vezi și acest răspuns stackoverflow.com/a/39831952/676571 –  > Por clearpath.
15 răspunsuri
Rahul Tripathi

Nu puteți utiliza ALTER TABLE withcaz.

Căutați să obțineți numele coloanelor pentru o tabelă::-

PRAGMA table_info(table-name);

Verificați acest tutorial pe PRAGMA

Această pragmă returnează un rând pentru fiecare coloană din tabelul numit. Coloanele din setul de rezultate includ numele coloanei, tipul de date, dacă coloana poate fi sau nu NULL și valoarea implicită pentru coloană. Coloana „pk” din setul de rezultate este zero pentru coloanele care nu fac parte din cheia primară și este indicele coloanei din cheia primară pentru coloanele care fac parte din cheia primară.

Comentarii

  • puteți face ceva de genul: PRAGMA table_info(QAQC_Tasks) WHERE name = „syncstatus”; ? –  > Por Herrozerro.
  • Nu a funcționat. „Near WHERE: ‘Syntax Error'” Cred că am vrut să întreb dacă așa ceva este posibil. –  > Por Herrozerro.
  • există o modalitate de a folosi pragma? Tocmai am încercat SELECT name FROM PRAGMA table_info(QAQC_Tasks) WHERE name = „BusinessUnit”; fără succes. –  > Por Herrozerro.
  • Ce se întâmplă dacă cineva trebuie să rezolve acest lucru folosind declarația SQL și nu poate folosi codul pentru a itera prin toate coloanele? –  > Por Igor Meszaros.
  • Cum să verificați dacă o coloană există în declarația sql? –  > Por Bagusflyer.
Formentz

Deși este o întrebare veche, am găsit la Funcțiile PRAGMA o soluție mai simplă:

SELECT COUNT(*) AS CNTREC FROM pragma_table_info('tablename') WHERE name='column_name'

Dacă rezultatul este mai mare decât zero, atunci coloana există. Interogare simplă și pe o singură linie

Trucul constă în utilizarea

pragma_table_info('tablename')

în loc de

PRAGMA table_info(tablename)

Editați: Vă rugăm să rețineți că, așa cum s-a raportat în Funcțiile PRAGMA:

Această funcție este experimentală și este supusă modificărilor. O documentație suplimentară va fi disponibilă în cazul în care și atunci când funcția de funcții cu valoare de tabel pentru PRAGMA va fi susținută oficial.

Caracteristica funcții cu valoare de tabel pentru PRAGMA a fost adăugată în versiunea SQLite 3.16.0 (2017-01-02). Versiunile anterioare ale SQLite nu pot utiliza această caracteristică.

Comentarii

  • Nu funcționează. Se afișează: Nu există un astfel de tabel: pragma_table_info: –  > Por Bagusflyer.
  • @Zhou Hao Poate că folosiți o versiune mai veche de SQLite? Vă rugăm să încercați să vă uitați la link-ul din răspunsul meu, această abordare este documentată –  > Por Formentz.
  • Trebuie menționat faptul că această caracteristică este considerată experimentală și poate fi modificată dacă este nevoie de ea. De asemenea, caracteristica a fost adăugată la versiunea 3.16.0 (2017-01-02). –  > Por Smar.
  • Error: no such table: pragma_table_info cu sqlite3 v3.11.0 2016-02-15 –  > Por Katie.
  • @Katie: așa cum am raportat în postarea mea, funcția este disponibilă doar de la v. 3.16.0, versiunea dvs. este mai veche –  > Por Formentz.
Pankaj Jangid
// This method will check if column exists in your table
public boolean isFieldExist(String tableName, String fieldName)
{
     boolean isExist = false;
     SQLiteDatabase db = this.getWritableDatabase();
     Cursor res = db.rawQuery("PRAGMA table_info("+tableName+")",null);
    res.moveToFirst();
    do {
        String currentColumn = res.getString(1);
        if (currentColumn.equals(fieldName)) {
            isExist = true;
        }
    } while (res.moveToNext());
     return isExist;
}

Comentarii

  • nu funcționează exact, trebuia să o rezolv, dar ideea îmi dă soluția… mulțumesc!!! –  > Por andrey2ag.
  • În ce limbă este scris acest lucru? –  > Por Thomas.
  • @Thomas Java bazat pe clase specifice Android –  > Por MatPag.
  • frumos exemplu. aici este traducerea iOS Objective-C folosind FMDatabaseQueue: ` FMDatabaseQueueue *Zqueue = [FMDatabaseQueueue databaseQueueueWithPath:[AppConfiguration offlineDbPath]]]; [Zqueue inDatabase:^(FMDatabase *db) { FMResultSet *res = [db executeQuery: @”PRAGMA table_info(my_table)”]]; int colExistsIndex = [res columnIndexForName:@”my_col”]; if (colExistsIndex < 0) { // creează coloana } }];` –  > Por eGanges.
  • Am corectat acest răspuns și am postat aici. –  > Por Adil Hussain.
TechNyquist

Nu ați specificat un limbaj, așa că, presupunând că nu este pur sql, puteți verifica dacă există erori la interogarea coloanelor:

SELECT col FROM table;

dacă primești o eroare, atunci știi că coloana nu există (presupunând că știi că tabelul există, oricum ai „IF NOT EXISTS” pentru asta), altfel coloana există și atunci poți modifica tabelul în consecință.

Giancarlo Sereni

Am aplicat această soluție:

public boolean isFieldExist(SQLiteDatabase db, String tableName, String fieldName)
    {
        boolean isExist = false;

        Cursor res = null;

        try {

            res = db.rawQuery("Select * from "+ tableName +" limit 1", null);

            int colIndex = res.getColumnIndex(fieldName);
            if (colIndex!=-1){
                isExist = true;
            }

        } catch (Exception e) {
        } finally {
            try { if (res !=null){ res.close(); } } catch (Exception e1) {}
        }

        return isExist;
    }

Este o variantă a codului lui Pankaj Jangid.

Comentarii

  • Întrebarea cere o interogare SQL, nu un cod Java sau C++. –  > Por Katie.
Parimal Raj

Un mod ciudat de a verifica dacă există o coloană

public static bool SqliteColumnExists(this SQLiteCommand cmd, string table, string column)
{
    lock (cmd.Connection)
    {
        // make sure table exists
        cmd.CommandText = string.Format("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = '{0}'", table);
        var reader = cmd.ExecuteReader();

        if (reader.Read())
        {
            //does column exists?
            bool hascol = reader.GetString(0).Contains(String.Format(""{0}"", column));
            reader.Close();
            return hascol;
        }
        reader.Close();
        return false;
    }
}

Comentarii

  • Întrebarea solicită o interogare SQL, nu cod Java sau C++. –  > Por Katie.
Oleksandr Pyrohov

Pentru a obține nume de coloane pentru o tabelă:

PRAGMA table_info (tableName);

Pentru a obține coloane indexate:

PRAGMA index_info (indexName);

Guru raj

Utilizați cu un try, catch și finally pentru orice execuție rawQuery() pentru practici mai bune. Iar următorul cod vă va oferi rezultatul.

public boolean isColumnExist(String tableName, String columnName)
{
    boolean isExist = false;
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = null;
    try {
        cursor = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);
        if (cursor.moveToFirst()) {
            do {
                String currentColumn = cursor.getString(cursor.getColumnIndex("name"));
                if (currentColumn.equals(columnName)) {
                    isExist = true;
                }
            } while (cursor.moveToNext());

        }
    }catch (Exception ex)
    {
        Log.e(TAG, "isColumnExist: "+ex.getMessage(),ex );
    }
    finally {
        if (cursor != null)
            cursor.close();
        db.close();
    }
    return isExist;
}

jakir hussain

Actualizați DATABASE_VERSION, astfel încât funcția onUpgrade să fie apelată și dacă există deja o coloană, atunci nu se întâmplă nimic, dacă nu, atunci se va adăuga o nouă coloană.

 private static class OpenHelper extends SQLiteOpenHelper {

OpenHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


    if (!isColumnExists(db, "YourTableName", "YourColumnName")) {

        try {

            String sql = "ALTER TABLE " + "YourTableName" + " ADD COLUMN " + "YourColumnName" + "TEXT";
            db.execSQL(sql);

        } catch (Exception localException) {
            db.close();
        }

    }


}

}

 public static boolean isColumnExists(SQLiteDatabase sqliteDatabase,
                                     String tableName,
                                     String columnToFind) {
    Cursor cursor = null;

    try {
        cursor = sqliteDatabase.rawQuery(
                "PRAGMA table_info(" + tableName + ")",
                null
        );

        int nameColumnIndex = cursor.getColumnIndexOrThrow("name");

        while (cursor.moveToNext()) {
            String name = cursor.getString(nameColumnIndex);

            if (name.equals(columnToFind)) {
                return true;
            }
        }

        return false;
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
}

Comentarii

  • Întrebarea solicită o interogare SQL, nu un cod Java sau C++. –  > Por Katie.
Colonel Treizeci și doi

Similar cu IF în SQLite, CASE în SQLite este un expresie. Nu puteți utiliza ALTER TABLE cu ea. A se vedea: http://www.sqlite.org/lang_expr.html

Jaro B
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');

…fiți atenți la condiția LIKE care este imperfectă, dar pentru mine funcționează, deoarece toate coloanele mele au nume foarte unice…

Claus Elmann
  public static bool columExsist(string table, string column)
    {
        string dbPath = Path.Combine(Util.ApplicationDirectory, "LocalStorage.db");

        connection = new SqliteConnection("Data Source=" + dbPath);
        connection.Open();

        DataTable ColsTable = connection.GetSchema("Columns");

        connection.Close();

        var data = ColsTable.Select(string.Format("COLUMN_NAME='{1}' AND TABLE_NAME='{0}1'", table, column));

        return data.Length == 1;
    }

andrey2ag

Am actualizat funcția unui prieten… am testat și funcționează acum

    public boolean isFieldExist(String tableName, String fieldName)
{
    boolean isExist = false;
    SQLiteDatabase db = this.getWritableDatabase();
    Cursor res = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);


    if (res.moveToFirst()) {
        do {
            int value = res.getColumnIndex("name");
            if(value != -1 && res.getString(value).equals(fieldName))
            {
                isExist = true;
            }
            // Add book to books

        } while (res.moveToNext());
    }

    return isExist;
}

Comentarii

  • Acesta este modul corect de a procesa cursorul provenit din interogarea PRAGMA. Tocmai am făcut acest lucru în aplicația mea. –  > Por kris larson.
Abdul Yasin

Îmi pare foarte rău că am postat-o târziu. Postarea în intenția de poate fi de ajutor în cazul cuiva.

Am încercat să extrag coloana din baza de date. Dacă returnează un rând, acesta conține acea coloană, altfel nu…

-(BOOL)columnExists { 
 BOOL columnExists = NO;

//Retrieve the values of database
const char *dbpath = [[self DatabasePath] UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK){

    NSString *querySQL = [NSString stringWithFormat:@"SELECT lol_10 FROM EmployeeInfo"];
    const char *query_stmt = [querySQL UTF8String];

    int rc = sqlite3_prepare_v2(database ,query_stmt , -1, &statement, NULL);
    if (rc  == SQLITE_OK){
        while (sqlite3_step(statement) == SQLITE_ROW){

            //Column exists
            columnExists = YES;
            break;

        }
        sqlite3_finalize(statement);

    }else{
        //Something went wrong.

    }
    sqlite3_close(database);
}

return columnExists; 
}

Comentarii

  • Ce se întâmplă dacă coloana există dar nu există intrări? –  > Por Abbas.
4gus71n

Unele dintre aceste exemple nu au funcționat pentru mine. Încerc să verific dacă tabelul meu conține deja o coloană sau nu.

Folosesc acest snippet:

public boolean tableHasColumn(SQLiteDatabase db, String tableName, String columnName) {
    boolean isExist = false;
    Cursor cursor = db.rawQuery("PRAGMA table_info("+tableName+")",null);
    int cursorCount = cursor.getCount();
    for (int i = 1; i < cursorCount; i++ ) {
        cursor.moveToPosition(i);
        String storedSqlColumnName = cursor.getString(cursor.getColumnIndex("name"));
        if (columnName.equals(storedSqlColumnName)) {
            isExist = true;
        }
    }
    return isExist;
}

Exemplele de mai sus interoghează tabelul pragma, care este un tabel de metadate și nu datele reale, fiecare coloană indică numele, tipul și alte câteva lucruri despre coloanele tabelului. Deci, numele coloanelor reale se află în interiorul rândurilor.

Sper că acest lucru ajută pe altcineva.

Tags: