Sqlite中判斷表、欄位是否存在的方法
sqlite會自動維護一個系統表sqlite_master,該表儲存了我們所建立的各個table, view, trigger等等資訊。
sqlite_master表資料欄位:
type: 型別,取值一般為table, view name: tbl_name: 表名 rootpage:sql:建立表或者檢視的sql語句,可以從該sql語句中判斷某欄位是否存在
sqlite_master表結構如下:
- CREATE TABLE sqlite_master (
- type TEXT,
- name TEXT,
- tbl_name TEXT,
- rootpage INTEGER,
- sql TEXT
- );
CREATE TABLE sqlite_master (
type TEXT,
name TEXT,
tbl_name TEXT,
rootpage INTEGER,
sql TEXT
);
例如:
[sql]
view plain
copy
print?
- select * from sqlite_master where type = 'table' and name = 't_cmpt_cp'
select * from sqlite_master where type = 'table' and name = 't_cmpt_cp'
sql執行結果是:
1. 查詢與判斷表
查詢sqlite中所有表,可用如下sql語句。
[sql] view plain copy print?- select name from sqlite_master where type='table' order by name;
select name from sqlite_master where type='table' order by name;
我們可以通過如下語句檢視這個內建表的所有記錄:
- select * from sqlite_master
select * from sqlite_master
執行結果:
由此可以進一步引申:判斷指定的表是否存在,可以用如下語句:
[sql] view plain copy print?- select count(*) from sqlite_master where type='table' and name = 'yourtablename';
select count(*) from sqlite_master where type='table' and name = 'yourtablename';
或者
其中yourtablename表示你要判斷的表名,如果查詢結果大於0,表示該表存在於資料庫中,否則不存在。
2. 查詢與判斷列
通過以下語句可查詢出某個表的所有欄位資訊
PRAGMA table_info([tablename])
比如:我想查看錶catalog的所有列資訊,可以用下述程式碼,結果如圖所示:
PRAGMA table_info(t_cmpt_cp)
判斷某列是否存在的方法:
方法1:
[java] view plain copy print?- /**
- * 檢查表中某列是否存在
- * @param db
- * @param tableName 表名
- * @param columnName 列名
- * @return
- */
- private boolean checkColumnExists2(SQLiteDatabase db, String tableName
- , String columnName) {
- boolean result = false ;
- Cursor cursor = null ;
- try{
- cursor = db.rawQuery( "select * from sqlite_master where name = ? and sql like ?"
- , new String[]{tableName , "%" + columnName + "%"} );
- result = null != cursor && cursor.moveToFirst() ;
- }catch (Exception e){
- Log.e(TAG,"checkColumnExists2..." + e.getMessage()) ;
- }finally{
- if(null != cursor && !cursor.isClosed()){
- cursor.close() ;
- }
- }
- return result ;
- }
/**
* 檢查表中某列是否存在
* @param db
* @param tableName 表名
* @param columnName 列名
* @return
*/
private boolean checkColumnExists2(SQLiteDatabase db, String tableName
, String columnName) {
boolean result = false ;
Cursor cursor = null ;
try{
cursor = db.rawQuery( "select * from sqlite_master where name = ? and sql like ?"
, new String[]{tableName , "%" + columnName + "%"} );
result = null != cursor && cursor.moveToFirst() ;
}catch (Exception e){
Log.e(TAG,"checkColumnExists2..." + e.getMessage()) ;
}finally{
if(null != cursor && !cursor.isClosed()){
cursor.close() ;
}
}
return result ;
}
方法2:
- /**
- * 判斷某表裡某欄位是否存在
- *
- * @param db
- * @param tableName
- * @param fieldName
- * @return
- */
- private boolean isFieldExist(SQLiteDatabase db, String tableName, String fieldName) {
- String queryStr = "select sql from sqlite_master where type = 'table' and name = '%s'";
- queryStr = String.format(queryStr, tableName);
- Cursor c = db.rawQuery(queryStr, null);
- String tableCreateSql = null;
- try {
- if (c != null && c.moveToFirst()) {
- tableCreateSql = c.getString(c.getColumnIndex("sql"));
- }
- } finally {
- if (c != null)
- c.close();
- }
- if (tableCreateSql != null && tableCreateSql.contains(fieldName))
- return true;
- return false;
- }
/**
* 判斷某表裡某欄位是否存在
*
* @param db
* @param tableName
* @param fieldName
* @return
*/
private boolean isFieldExist(SQLiteDatabase db, String tableName, String fieldName) {
String queryStr = "select sql from sqlite_master where type = 'table' and name = '%s'";
queryStr = String.format(queryStr, tableName);
Cursor c = db.rawQuery(queryStr, null);
String tableCreateSql = null;
try {
if (c != null && c.moveToFirst()) {
tableCreateSql = c.getString(c.getColumnIndex("sql"));
}
} finally {
if (c != null)
c.close();
}
if (tableCreateSql != null && tableCreateSql.contains(fieldName))
return true;
return false;
}
方法3:根據 cursor.getColumnIndex(String columnName) 的返回值判斷,如果為-1表示表中無此欄位
[java] view plain copy print?- /**
- * 檢查某表列是否存在
- * @param db
- * @param tableName 表名
- * @param columnName 列名
- * @return
- */
- private boolean checkColumnExist1(SQLiteDatabase db, String tableName
- , String columnName) {
- boolean result = false ;
- Cursor cursor = null ;
- try{
- //查詢一行
- cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0"
- , null );
- result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;
- }catch (Exception e){
- Log.e(TAG,"checkColumnExists1..." + e.getMessage()) ;
- }finally{
- if(null != cursor && !cursor.isClosed()){
- cursor.close() ;
- }
- }
- return result ;
- }
/**
* 檢查某表列是否存在
* @param db
* @param tableName 表名
* @param columnName 列名
* @return
*/
private boolean checkColumnExist1(SQLiteDatabase db, String tableName
, String columnName) {
boolean result = false ;
Cursor cursor = null ;
try{
//查詢一行
cursor = db.rawQuery( "SELECT * FROM " + tableName + " LIMIT 0"
, null );
result = cursor != null && cursor.getColumnIndex(columnName) != -1 ;
}catch (Exception e){
Log.e(TAG,"checkColumnExists1..." + e.getMessage()) ;
}finally{
if(null != cursor && !cursor.isClosed()){
cursor.close() ;
}
}
return result ;
}
3. Sqlite中新增、刪除、重新命名列
3.1 新增一列
方法:使用sql命令
命令:ALTER TABLE table-name ADD COLUMN column-name column-type
例如:在student表中新增一列名為name,型別為varchar:
alter table student add column name varchar;
alter table catalog add column xxx1 char(20) default '';
3.2 刪除一列
方法:由於drop命令在sqlite中不可用於刪除列,
alter table student drop column name // 該行在SQlite中不能用,SQlite不支援drop
可採用如下思路,類似於swap()函式的過程。
比如我有表A,A中有x、y、z三列。我要將表A中的x列刪掉。那麼,
第1步,新建一個表B,B中含有y、z兩個欄位,且型別與A中的y、z型別相同。
第2步,將A中的所有y、z兩列的值拷貝到B中。
上面兩步使用一句命令即可完成
create table B as select y,z from A
注意,如果A中y的型別為char,則上面create命令會在B中建立型別為TEXT的y列。即char型別會被改變。
第3步,將A表刪除
drop table if exists A
第4步,將B重新命名為A
alter table B rename to A
3.3 重新命名一列
方法:與刪除一列相同,在sqlite中alter同樣無法重新命名一列。如果想重新命名,那麼思路與刪除一列相同。
4. Sqlite中新增、刪除、重命名錶
Sql語句在3.2中已有。整理如下。
4.1 新增表
create table A(id char(20),channeltext,name text,primary key (id))
create table B as select y,z from A
4.2 刪除表
drop table if exists A
4.3 重命名錶
alter table B rename to A