我需要检查列是否存在,如果不存在则添加它。根据我的研究,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);
但我收到错误:Near“ALTER”:语法错误。
有什么想法吗?
您不能使用
ALTER TABLE with
case.
您正在寻找获取表的列名称::-
PRAGMA table_info(table-name);
在 PRAGMA
上查看本教程此编译指示为指定表中的每一列返回一行。 结果集中的列包括列名、数据类型、是否 或不该列可以为NULL,并为该列的默认值。 对于不存在的列,结果集中的“pk”列为零 主键的一部分,是主键中列的索引 作为主键一部分的列的键。
虽然这是一个老问题,但我在PRAGMA函数找到了一个更简单的解决方案:
SELECT COUNT(*) AS CNTREC FROM pragma_table_info('tablename') WHERE name='column_name'
如果结果大于零,则该列存在。简单的一行查询
秘诀就是使用
pragma_table_info('tablename')
而不是
PRAGMA table_info(tablename)
编辑:请注意,如PRAGMA函数中所述:
在 SQLite 版本 3.16.0 (2017-01-02) 中添加了 PRAGMA 功能的表值函数。之前版本的 SQLite 无法使用此功能
// 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;
}
你没有指定语言,所以假设它不是纯sql,你可以检查列查询上的错误:
SELECT col FROM table;
如果您收到错误,那么您知道该列不存在(假设您知道该表存在,无论如何您都有“IF NOT EXISTS”),否则该列存在,然后您可以相应地更改表。
我已经应用了这个解决方案:
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 的代码变体。
在任何 rawQuery() 执行中使用 try、catch 和 finally 以获得更好的实践。下面的代码会给你结果。
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;
}
SELECT EXISTS (SELECT * FROM sqlite_master WHERE tbl_name = 'TableName' AND sql LIKE '%ColumnName%');
..请注意 LIKE 条件是不完美的,但它对我有用,因为我所有的列都有非常独特的名称..
检查现有列的奇怪方法
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;
}
}
获取表的列名称:
PRAGMA table_info (tableName);
要获取索引列:
PRAGMA index_info (indexName);
我在 SQLite 3.13.0 中使用了以下
SELECT
语句
SELECT INSTR(sql, '<column_name>') FROM sqlite_master WHERE type='table' AND name='<table_name>';
如果表
<column_name>
中不存在列 <table_name>
,则返回 0(零)。
我更新了朋友的功能...已测试并正在工作
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;
}
更新 DATABASE_VERSION 以便调用 onUpgrade 函数,然后如果列已经存在,则不会发生任何事情,如果不存在,则会添加新列。
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();
}
}
}
与 SQLite 中的
IF
类似,SQLite 中的 CASE
是一个 表达式。您不能将 ALTER TABLE
与它一起使用。请参阅:http://www.sqlite.org/lang_expr.html
我真的很抱歉迟到了。发帖意图可能对某人的情况有帮助。
我尝试从数据库中获取该列。如果它返回一行,则它包含该列,否则不...
-(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;
}
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;
}
其中一些示例对我不起作用。我正在尝试检查我的表是否已包含列。
我正在使用这个片段:
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 表,它是一个元数据表,而不是实际数据,每一列表示名称、类型和有关表列的一些其他内容。因此实际的列名称位于行内。
希望这对其他人有帮助。
SELECT INSTR(Lower(sql), " exceptionclass ") FROM sqlite_master WHERE type="table" AND Lower(name)="bugsgroup";
Select * FROM pragma_table_xinfo('my table') WHERE lower(name) = 'myCol';