Проверьте, существует ли столбец SQLite
Мне нужно проверить, существует ли столбец, и если он не существует, добавьте его. Из моих исследований похоже, что 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": ошибка синтаксиса.
Любые идеи?
Ответы
Ответ 1
Вы не можете использовать ALTER TABLE with
case .
Вы ищете имена столбцов для таблицы:: -
PRAGMA table_info(table-name);
Проверьте этот учебник на PRAGMA
Эта прагма возвращает одну строку для каждого столбца в названной таблице. Столбцы в наборе результатов включают имя столбца, тип данных, независимо от того, или нет, столбец может быть NULL и значением по умолчанию для столбца. Столбец "pk" в наборе результатов равен нулю для столбцов, которые не являются часть первичного ключа и является индексом столбца в первичной ключ для столбцов, которые являются частью первичного ключа.
Ответ 2
// 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;
}
Ответ 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:
Эта функция является экспериментальной и может быть изменена. Дальнейшая документация станет доступной, если и когда официально будут поддерживаться табличные функции для функции PRAGMA.
Табличные функции для функции PRAGMA были добавлены в SQLite версии 3.16.0 (2017-01-02). Предыдущие версии SQLite не могли использовать эту функцию.
Ответ 4
Я применил это решение:
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;
}
Это вариант кода Панкаджа Джангида.
Ответ 5
Вы не указали язык, поэтому, предполагая, что он не является чистым sql, вы можете проверить наличие ошибок в запросе столбцов:
SELECT col FROM table;
если вы получили сообщение об ошибке, чтобы вы знали, что столбец не существует (если вы знаете, что таблица существует, в любом случае у вас есть "ЕСЛИ НЕ СУЩЕСТВУЕТ" ), в противном случае столбец существует, а затем вы можете соответствующим образом изменить таблицу.
Ответ 6
Чтобы получить имена столбцов для таблицы:
PRAGMA table_info (tableName);
Чтобы получить индексированные столбцы:
PRAGMA index_info (indexName);
Ответ 7
Странный способ проверить существующий столбец
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;
}
}
Ответ 8
Обновите 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();
}
}
}
Ответ 9
Подобно IF
в SQLite, CASE
в SQLite является выражением. Вы не можете использовать ALTER TABLE
с ним. См.: http://www.sqlite.org/lang_expr.html
Ответ 10
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;
}
Ответ 11
Я обновил функцию друга... проверял и работал сейчас
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;
}
Ответ 12
Мне очень жаль, что вы опоздали. Проводка в намерении может быть полезна в чьем-то случае.
Я попытался извлечь столбец из базы данных. Если он возвращает строку, он содержит этот столбец иначе...
-(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;
}
Ответ 13
Pankaj Jangid ответ близок, но не совсем корректен. Здесь это с исправлениями:
public 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();
}
}
}
Ответ 14
Некоторые из этих примеров не сработали для меня. Я пытаюсь проверить, содержит ли моя таблица столбец или нет.
Я использую этот фрагмент:
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;
}
Приведенные выше примеры запрашивают таблицу прагмы, которая является таблицей метаданных, а не фактическими данными, каждый столбец указывает имена, тип и некоторые другие элементы в столбцах таблицы. Таким образом, фактические имена столбцов находятся внутри строк.
Надеюсь, что это поможет кому-то другому.
Ответ 15
Используйте с 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;
}