SQLite sqlite_master

本文深入探讨了SQLite数据库中sqlite_master表的结构和用途。详细介绍了该表的字段及其意义,包括如何通过查询该表来获取数据库内的表、索引、视图和触发器等元信息。
一 简述
  1. 每一个 SQLite 数据库都有一个叫 sqlite_master 的表,该表会自动创建。
  2. sqlite_master是一个特殊表, 存储数据库的元信息, 如表(table), 索引(index), 视图(view), 触发器(trigger), 可通过select查询相关信息。
二 表结构
  1. 基本信息
PRAGMA  table_info(sqlite_master) 
  • 结果如下:
cidnametypenotnulldflt_valuepk
0typetext0(null)0
1nametext0(null)0
2tbl_nametext0(null)0
3rootpageint0(null)0
4sqltext0(null)0
  1. 字段说明
字段意义
type记录项目的类型,如table、index、view、trigger
name记录项目的名称,如表名、索引名等
tbl_name记录所从属的表名,如索引所在的表名。对于表来说,该列就是表名本身
rootpage记录项目在数据库页中存储的编号。对于视图和触发器,该列值为0或者NULL
sql记录创建该项目的SQL语句
三 举例
  1. 查表
select name from sqlite_master where type = 'table' order by name; 

在这里插入图片描述

  1. 查所有
select * from sqlite_master;

在这里插入图片描述

四 说明
  1. 可通过sqlite_master表判断特定的表、视图或者索引是否存在。
select count(*) from sqlite_master where type = 'table' and name = 'reply';// 1
  1. sqlite_temp_master专门用来存储临时表的信息,此表和sqlite_master表的结构一致。
static int openDatabase( const char *zFilename, /* Database filename UTF-8 encoded */ sqlite3 **ppDb, /* OUT: Returned database handle */ sqlite3_area_info *area,/* db area info */ int wal_cnt, /* db max wal cnt */ unsigned int flags, /* Operational flags */ const char *zVfs /* Name of the VFS to use */ ){ sqlite3 *db; /* Store allocated handle here */ int rc; /* Return code */ int isThreadsafe; /* True for threadsafe connections */ char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */ char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */ #ifdef SQLITE_ENABLE_API_ARMOR if( ppDb==0 ) return SQLITE_MISUSE_BKPT; #endif *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ) return rc; #endif /* Only allow sensible combinations of bits in the flags argument. ** Throw an error if any non-sense combination is used. If we ** do not block illegal combinations here, it could trigger ** assert() statements in deeper layers. Sensible combinations ** are: ** ** 1: SQLITE_OPEN_READONLY ** 2: SQLITE_OPEN_READWRITE ** 6: SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE */ assert( SQLITE_OPEN_READONLY == 0x01 ); assert( SQLITE_OPEN_READWRITE == 0x02 ); assert( SQLITE_OPEN_CREATE == 0x04 ); testcase( (1<<(flags&7))==0x02 ); /* READONLY */ testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ if( ((1<<(flags&7)) & 0x46)==0 ){ return SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ } if( sqlite3GlobalConfig.bCoreMutex==0 ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_NOMUTEX ){ isThreadsafe = 0; }else if( flags & SQLITE_OPEN_FULLMUTEX ){ isThreadsafe = 1; }else{ isThreadsafe = sqlite3GlobalConfig.bFullMutex; } if( flags & SQLITE_OPEN_PRIVATECACHE ){ flags &= ~SQLITE_OPEN_SHAREDCACHE; }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ flags |= SQLITE_OPEN_SHAREDCACHE; } /* Remove harmful bits from the flags parameter ** ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were ** dealt with in the previous code block. Besides these, the only ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask ** off all other flags. */ flags &= ~( SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TRANSIENT_DB | SQLITE_OPEN_MAIN_JOURNAL | SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_MASTER_JOURNAL | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_WAL ); /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; if( isThreadsafe ){ db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ sqlite3_free(db); db = 0; goto opendb_out; } } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; db->autoCommit = 1; db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX | SQLITE_AutoIndex #endif #if SQLITE_DEFAULT_CKPTFULLFSYNC | SQLITE_CkptFullFSync #endif #if SQLITE_DEFAULT_FILE_FORMAT<4 | SQLITE_LegacyFileFmt #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension #endif #if SQLITE_DEFAULT_RECURSIVE_TRIGGERS | SQLITE_RecTriggers #endif #if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS | SQLITE_ForeignKeys #endif #if defined(SQLITE_REVERSE_UNORDERED_SELECTS) | SQLITE_ReverseOrder #endif #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) | SQLITE_CellSizeCk #endif #if defined(SQLITE_ENABLE_FTS3_TOKENIZER) | SQLITE_Fts3Tokenizer #endif ; sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3HashInit(&db->aModule); #endif /* Add the default collation sequence BINARY. BINARY works for both UTF-8 ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. ** ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating ** functions: */ createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } /* EVIDENCE-OF: R-08308-17224 The default collating function for all ** strings is BINARY. */ db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); assert( db->pDfltColl!=0 ); /* Parse the filename/URI argument. */ db->openFlags = flags; rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); sqlite3_free(zErrMsg); goto opendb_out; } /* Open the backend database driver */ rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, area, wal_cnt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM_BKPT; } sqlite3Error(db, rc); goto opendb_out; } sqlite3BtreeEnter(db->aDb[0].pBt); db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); sqlite3BtreeLeave(db->aDb[0].pBt); db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. */ db->aDb[0].zDbSName = "main"; db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; db->aDb[1].zDbSName = "temp"; db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; db->magic = SQLITE_MAGIC_OPEN; if( db->mallocFailed ){ goto opendb_out; } /* Register all built-in functions, but do not attempt to read the ** database schema yet. This is delayed until the first time the database ** is accessed. */ sqlite3Error(db, SQLITE_OK); sqlite3RegisterPerConnectionBuiltinFunctions(db); rc = sqlite3_errcode(db);代码太长,先给你一部分,给我详细解释一下
最新发布
09-19
其SQL語 句的格式為: create table table_name (column_name1 column_type, column_name2 column_type, …); 例如: create table Student(stud_no text primary key, stud_name text); 如果你想知道學號為‘102’以外的學生名字,可以寫如下: select stud_no, stud_name from Student where stud_no ‘102’ ; 如果你想知道學號不是‘101’,而且學生名字不是‘Linda’的資料,可以寫為: select stud_name from Student where stud_no ‘101’ and stud_name ‘Linda’; 這就把兩個表格聯結起來: select Student.stud_name, Course.course_name from Student, Course where Student.stud_no = Course.stud_no; 這會進行加總了: select SUM(score1), SUM(score2) from New_Course; 還可計算平均值: select AVG(score1), AVG(score2) from New_Course New_Course 表格 course_name stud_no score1 score2 DATABASE 101 70.0 74.5 ART 101 60.0 45.0 DATABASE 102 95.0 90.5 GROUP BY 子句可建立比較小的組(Group),並且對每一個組進行加總等運 算。換句話說,它產生每一組的整體性資訊。例如: select course_name, SUM(score1), SUM(score2) from New_Course group by course_name 得出結果為: course_name SUM(score1) SUM(score2) DATABASE 165.0 165.0 ART 60.0 45.0 藉由 GROUP BY 語句,可以讓 SUM()等函數對屬於一組的資料進行運算。當 你指定「GROUP BY 區域」時, 屬於同一個區域的一組資料將只會得到一行 (Column)的值。◆ private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) {} @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} } private DatabaseHelper mOpenHelper; public void onClick(View v){ if (v == btn){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql = "create table Student(" + "stud_no text not null, " + "stud_name text );"; try { db.execSQL(sql); setTitle("create table ok!"); } catch (SQLException e) { Log.e("ERROR", e.toString()); setTitle("create table Error!"); }} if (v == btn2){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql = "drop table Student"; try { db.execSQL(sql); setTitle("drop table ok!"); } catch (SQLException e) { Log.e("ERROR", e.toString()); setTitle("drop table Error!"); }} f (v == btn3){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql_1 = "insert into Student (stud_no, stud_name) values('S108', 'Lily Chen');"; String sql_2 = "insert into Student (stud_no, stud_name) values('S201', 'Tom Kao');"; String sql_3 = "insert into Student (stud_no, stud_name) values('S333', 'Peter Rabbit');"; try { db.execSQL(sql_1); db.execSQL(sql_2); db.execSQL(sql_3); setTitle("insert records ok!"); } catch (SQLException e) { Log.e("ERROR", e.toString()); } } if (v == btn4){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getReadableDatabase(); String col[] = {"stud_no", "stud_name" }; cur = db.query("Student", col, null, null, null, null, null); Integer n = cur.getCount(); String ss = Integer.toString(n); setTitle(ss + " records"); cur.moveToFirst(); } if (v == btn5) finish(); }} ***************8 private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE Student(" + "stud_no" + " TEXT PRIMARY KEY," + "stud_name" + " TEXT" + ");"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} } @@@@@@@@@ if (v == btn3){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("stud_no", "S108"); cv.put("stud_name", "Lily Chen"); db.insert("Student", null, cv); cv = new ContentValues(); cv.put("stud_no", "S201"); cv.put("stud_name", "Tom Kao"); db.insert("Student", null, cv); cv = new ContentValues(); cv.put("stud_no", "S333"); cv.put("stud_name", "Peter Rabbit"); db.insert("Student", null, cv); setTitle("insert record ok!"); } if (v == btn4){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getReadableDatabase(); String col[] = {"stud_no", "stud_name" }; cur = db.query("Student", col, null, null, null, null, null); Integer n = cur.getCount(); String ss = Integer.toString(n); setTitle(ss + " records"); cur.moveToFirst(); } if (v == btn5){ if(!cur.isAfterLast()){ String ss = cur.getString(0) + ", " + cur.getString(1); setTitle(ss); cur.moveToNext(); } else setTitle("======"); } if (v == btn6){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("stud_no", "S288"); cv.put("stud_name", "Linda Wang"); db.update("Student", cv, "stud_no = 'S201'", null); } if (v == btn7){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.delete("Student", "stud_no = 'S108'", null); } if(v.equals(btn8)){ mOpenHelper = new DatabaseHelper(v.getContext()); SQLiteDatabase db = mOpenHelper.getWritableDatabase(); if (db != null) db.close(); this.finish(); }}} 1. 欲新增一筆資料時,上一個範例使用 SQL 語句來達成,如下: String sql = "insert into Student (stud_no, stud_name) values ('S108', 'Lily Chen');"; db.execSQL(sql_1); 在本範例則採用另一種途徑,將資料先存入 Android的 ContentValues物件裡, 然後將此物件當成參數而傳遞給 db.insert()函數,如下: ContentValues cv = new ContentValues(); cv.put("stud_no", "S108"); cv.put("stud_name", "Lily Chen"); db.insert("Student", null, cv); 2. 查詢時,把欲查出的欄位名稱存於字串陣列裡,再把它傳給 db.query()函數即 可。如下: String col[] = {"stud_no", "stud_name" }; cur = db.query("Student", col, null, null, null, null, null); Integer n = cur.getCount(); 查詢之後,db.query()回傳資料庫游標(Cursor)值給 cur,然後 cur.getCount()就 傳回所查到的資料筆數。 3. 指令: if( !cur.isAfterLast() ){ String ss = cur.getString(0) + ", " + cur.getString(1); // ……. cur.moveToNext(); } 由 cur.isAfterLast()判斷目前是否已經超出最後一筆資料了。如果不是,就藉由 cur.getString(0)取得第 1 個欄位的資料;而 cur.getString(0)取得第 2 個欄位的資 料值。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值