【问题标题】:Check if a column exists in SQLite检查 SQLite 中是否存在列
【发布时间】:2013-09-26 00:58:21
【问题描述】:

我需要检查一列是否存在,如果不存在则添加它。从我的研究看来,sqlite 不支持 IF 语句,应该使用 case 语句。

这是我目前所拥有的:

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);

但我收到错误:“ALTER”附近:语法错误。

有什么想法吗?

【问题讨论】:

标签: sqlite


【解决方案1】:
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');

..注意不完美的 LIKE 条件,但它对我有用,因为我的所有列都有非常独特的名称..

【讨论】:

    【解决方案2】:

    与 try、catch 和 finally 一起用于任何 rawQuery() 执行以获得更好的实践。下面的代码会给你结果。

    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;
    }
    

    【讨论】:

      【解决方案3】:

      虽然这是一个老问题,但我在PRAGMA functions 找到了一个更简单的解决方案:

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

      如果结果大于零,则该列存在。简单的一行查询

      诀窍是使用

      pragma_table_info('tablename')
      

      而不是

      PRAGMA table_info(tablename)
      

      编辑:请注意,如PRAGMA functions 中所述:

      此功能是实验性的,可能会发生变化。如果正式支持 PRAGMAs 功能的表值函数,将提供更多文档。

      在 SQLite 版本 3.16.0 (2017-01-02) 中添加了 PRAGMA 功能的表值函数。以前版本的 SQLite 无法使用此功能。

      【讨论】:

      • 不起作用。它显示:没有这样的表:pragma_table_info:
      • @Zhou Hao 也许您使用的是旧版本的 SQLite?请尝试查看我的答案中的链接,这种方法已记录在案
      • 需要说明的是,这个功能被认为是实验性的,如果有需要可能会改变。该功能还添加到版本 3.16.0 (2017-01-02)。
      • Error: no such table: pragma_table_info with sqlite3 v3.11.0 2016-02-15
      • @Katie:正如我的帖子中所报告的,该功能仅从 v. 3.16.0 开始可用,您的版本较旧
      【解决方案4】:
      // 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;
      }
      

      【讨论】:

      • 不能正常工作,需要修复它,但这个想法给了我解决方案......谢谢!!
      • 这是用什么语言写的?
      • @Thomas Java 基于 Android 特定类
      • 很好的例子。这是使用 FMDatabaseQueue 的 iOS Objective-C 翻译:` FMDatabaseQueue *Zqueue = [FMDatabaseQueue databaseQueueWithPath:[AppConfiguration offlineDbPath]]; [Zqueue inDatabase:^(FMDatabase *db) { FMResultSet *res = [db executeQuery:@"PRAGMA table_info(my_table)"]; int colExistsIndex = [res columnIndexForName:@“my_col”]; if (colExistsIndex
      • 我已经更正了这个答案并发布了here
      【解决方案5】:

      其中一些示例对我不起作用。我正在尝试检查我的表是否已经包含一列。

      我正在使用这个 sn-p:

      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;
      }
      

      上面的例子是查询pragma 表,它是一个元数据表而不是实际数据,每一列都指示了表列的名称、类型和其他一些东西。所以实际的列名在行内。

      希望这对其他人有所帮助。

      【讨论】:

        【解决方案6】:

        更新 DATABASE_VERSION 以便调用 onUpgrade 函数,然后如果 Column 已经存在,则不会发生任何事情,否则它将添加新列。

         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();
                }
            }
        }
        

        【讨论】:

        • 该问题要求的是 SQL 查询,而不是 Java 或 C++ 代码。
        【解决方案7】:

        获取表的列名:

        PRAGMA table_info (tableName);
        

        获取索引列:

        PRAGMA index_info (indexName);
        

        【讨论】:

          【解决方案8】:

          我真的很抱歉迟到了。发帖的意图可能对某人的情况有所帮助。

          我尝试从数据库中获取列。如果它返回一行,则它包含该列,否则不...

          -(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; 
          }
          

          【讨论】:

          • 列存在但没有条目怎么办?
          【解决方案9】:

          我更新了一个朋友的功能......现在已经测试并且可以工作了

              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;
          }
          

          【讨论】:

          • 这是处理来自 PRAGMA 查询的光标的正确方法。刚刚在我的应用中这样做了。
          【解决方案10】:

          我已经应用了这个解决方案:

          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;
              }
          

          它是 Pankaj Jangid 的代码变体。

          【讨论】:

          • 该问题要求的是 SQL 查询,而不是 Java 或 C++ 代码。
          【解决方案11】:
            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;
              }
          

          【讨论】:

            【解决方案12】:

            你没有指定语言,所以假设它不是纯sql,你可以检查列查询的错误:

            SELECT col FROM table;
            

            如果您收到错误,因此您知道该列不存在(假设您知道该表存在,无论如何您对此都有“如果不存在”),否则该列存在,然后您可以相应地更改该表。

            【讨论】:

              【解决方案13】:

              检查现有列的奇怪方法

              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;
                  }
              }
              

              【讨论】:

              • 该问题要求的是 SQL 查询,而不是 Java 或 C++ 代码。
              【解决方案14】:

              你不能使用ALTER TABLE withcase.

              您正在寻找获取表的列名::-

              PRAGMA table_info(table-name);
              

              PRAGMA查看本教程

              此编译指示为命名表中的每一列返回一行。 结果集中的列包括列名、数据类型、是否 该列是否可以为 NULL,以及该列的默认值。 结果集中的“pk”列对于不是的列为零 主键的一部分,是主键中列的索引 作为主键一部分的列的键。

              【讨论】:

              • 你能做类似的事情吗:PRAGMA table_info(QAQC_Tasks) WHERE name = "syncstatus"; ?
              • 它没有用。 “Near WHERE:'语法错误'”我想我是想问这样的事情是否可能。
              • 有没有办法使用编译指示?我刚试过 SELECT name FROM PRAGMA table_info(QAQC_Tasks) WHERE name = "BusinessUnit";没有运气。
              • @IulianOnofrei 这个方法会返回一个Cursor。然后您可以检查是否cursor.getColumnIndex("columnName") == -1
              • 如果有人必须使用 SQL 语句解决这个问题,而不能使用代码遍历所有列怎么办?
              【解决方案15】:

              类似于 SQLite 中的IF,SQLite 中的CASE 是一个表达式。您不能将ALTER TABLE 与它一起使用。见:http://www.sqlite.org/lang_expr.html

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-01-20
                • 2012-11-09
                • 1970-01-01
                • 1970-01-01
                • 2017-02-16
                • 2015-12-20
                相关资源
                最近更新 更多