SQlite資料庫的C編程介面(六) 傳回值和錯誤碼(Result Codes and Error Codes) ——《Using SQlite》讀書筆記

來源:互聯網
上載者:User

SQlite資料庫的C編程介面(六)  傳回值和錯誤碼(Result Codes
and Error Codes)  by斜風細雨QQ:253786989    2012-02-07

標準碼(Standard Codes

  下面是標準的傳回值和錯誤碼定義:

#define SQLITE_OK           0   /* Successful result *//* beginning-of-error-codes */#define SQLITE_ERROR        1   /* SQL error or missing database */#define SQLITE_INTERNAL     2   /* Internal logic error in SQLite */#define SQLITE_PERM         3   /* Access permission denied */#define SQLITE_ABORT        4   /* Callback routine requested an abort */#define SQLITE_BUSY         5   /* The database file is locked */#define SQLITE_LOCKED       6   /* A table in the database is locked */#define SQLITE_NOMEM        7   /* A malloc() failed */#define SQLITE_READONLY     8   /* Attempt to write a readonly database */#define SQLITE_INTERRUPT    9   /* Operation terminated by sqlite3_interrupt()*/#define SQLITE_IOERR       10   /* Some kind of disk I/O error occurred */#define SQLITE_CORRUPT     11   /* The database disk image is malformed */#define SQLITE_NOTFOUND    12   /* Unknown opcode in sqlite3_file_control() */#define SQLITE_FULL        13   /* Insertion failed because database is full */#define SQLITE_CANTOPEN    14   /* Unable to open the database file */#define SQLITE_PROTOCOL    15   /* Database lock protocol error */#define SQLITE_EMPTY       16   /* Database is empty */#define SQLITE_SCHEMA      17   /* The database schema changed */#define SQLITE_TOOBIG      18   /* String or BLOB exceeds size limit */#define SQLITE_CONSTRAINT  19   /* Abort due to constraint violation */#define SQLITE_MISMATCH    20   /* Data type mismatch */#define SQLITE_MISUSE      21   /* Library used incorrectly */#define SQLITE_NOLFS       22   /* Uses OS features not supported on host */#define SQLITE_AUTH        23   /* Authorization denied */#define SQLITE_FORMAT      24   /* Auxiliary database format error */#define SQLITE_RANGE       25   /* 2nd parameter to sqlite3_bind out of range */#define SQLITE_NOTADB      26   /* File opened that is not a database file */#define SQLITE_ROW         100  /* sqlite3_step() has another row ready */#define SQLITE_DONE        101  /* sqlite3_step() has finished executing *//* end-of-error-codes */

  其中有些常量只由具體的某個函數返回,比如SQLITE_RANGE只會由sqlite3_bind_xxx函數返回。還有一些常量,比如SQLITE_ERROR只能說明函數在執行過程中發生了錯誤,但無法知道錯誤發生的原因。

  SQLITE_MISUSE代表API被誤用。比如一條語句在sqlite3_step函數執行之後,沒有被重設之前,再次給其綁定參數,這時bind函數就會返回SQLITE_MISUSE。

擴充碼(Extended Codes

  標準錯誤碼對於錯誤發生的原因,所提供的資訊比較少。所以有時候,我們會使用擴充的錯誤碼。擴充錯誤碼是以標準錯誤碼為基礎,其低階位元組就是原本的標準錯誤碼,然後在其高階位元組“或”上附加資訊,描述錯誤發生的細節。

int sqlite3_extended_result_codes(sqlite3*, int onoff);

  因為考慮到客戶舊程式的相容性問題,預設情況下,這些擴充的錯誤碼是沒有啟用的。程式員可以通過sqlite3_extended_result_codes函數啟用或者關閉擴充錯誤碼。

  下面是所有的擴充錯誤碼(其中大部分用來描述SQLITE_IOERR):

#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))#define SQLITE_IOERR_LOCK              (SQLITE_IOERR | (15<<8))#define SQLITE_IOERR_CLOSE             (SQLITE_IOERR | (16<<8))#define SQLITE_IOERR_DIR_CLOSE         (SQLITE_IOERR | (17<<8))#define SQLITE_IOERR_SHMOPEN           (SQLITE_IOERR | (18<<8))#define SQLITE_IOERR_SHMSIZE           (SQLITE_IOERR | (19<<8))#define SQLITE_IOERR_SHMLOCK           (SQLITE_IOERR | (20<<8))#define SQLITE_IOERR_SHMMAP            (SQLITE_IOERR | (21<<8))#define SQLITE_IOERR_SEEK              (SQLITE_IOERR | (22<<8))#define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))#define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))#define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))#define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))#define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))#define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))

Error相關函數(Error Functions

int sqlite3_extended_result_codes(sqlite3*, int onoff);

  針對某個資料庫連接,啟用或關閉擴充錯誤碼的使用。通過給sqlite3_extended_result_codes函數的第2個參數傳遞非零值來啟用擴充錯誤碼。該函數總是返回SQLITE_OK,沒有什麼途徑可以擷取擴充錯誤碼當前是否啟用或關閉。

int sqlite3_errcode(sqlite3 *db);

  如果某個資料庫函數操作沒有返回SQLITE_OK,那麼可以隨後調用該函數擷取錯誤碼。預設情況下它返回標準錯誤碼,如果當前資料庫連接已經啟用了擴充錯誤碼,那麼該函數也可能會返回一個擴充的錯誤碼。

int sqlite3_extended_errcode(sqlite3 *db);

  與sqlite3_errcode函數類似,只不過該函數只會返回擴充的錯誤碼。

const char *sqlite3_errmsg(sqlite3*);const void *sqlite3_errmsg16(sqlite3*);

  返回錯誤碼字串,使用UTF-8或者UTF-16編碼。程式員應該在調用這兩個函數,擷取錯誤碼資訊之後立刻使用,或者做一個拷貝。因為下一個資料庫操作就可能會導致返回的字串指標失效。

  SQlite錯誤處理不能夠同時處理多個錯誤,比如某個API函數調用發生了錯誤,而程式員沒有對該錯誤進行檢查處理,那麼下一次API函數調用就很可能返回SQLITE_MISUSE,表明程式試圖使用一個無效的資料結構。所以程式員應該在每次API函數調用之後檢查和處理任何可能發生的錯誤。

  另外,如果多個線程分享同一個資料庫連接,最好將核心的API調用和錯誤處理部分的代碼封裝在關鍵代碼區(critical section)中。程式員可以使用sqlite3_db_mutex函數擷取資料庫連接的互斥鎖指標(一個指向sqlite3_mutex對象的指標)。

V2版本的prepare函數(Prepare v2

  下表是原版本的prepare函數和v2版本的prepare函數的比較:

  V2版本的prepare函數對於錯誤處理更簡潔,還有上表中列出的關於schema的優點,所以推薦使用v2版本的prepare函數。

事務和錯誤(Transactions and Errors

  通常,SQlite操作處於自動認可模式。SQlite自動把每一個SQL命令封裝進事務中。如果每條語句都被封裝進它自己的事務中,那錯誤恢複就簡單了。任何時候只要SQLite發現它自己處於錯誤狀態,只要簡單的復原當前事務就可以了。這樣就可以有效取消當前SQL命令,並使資料庫回到出錯之前的狀態。

  然而,一旦BEGIN TRANSACTION命令執行,SQlite就不在處於自動認可模式。一個事務被開啟,將一直保持開啟狀態直到END TRANSACTION或者COMMIT TRANSACTION命令執行。這就允許多條SQL命令封裝進一個事務中,使一系列離散的命令要麼全都執行,要麼都不執行(原子操作),不過這也限制了SQLite的錯誤恢複。

  當一個顯示的(explicit)事務執行過程中遇到一個錯誤,SQLite試圖取消剛剛執行的語句。不幸的是,這並不總是可能的。如果事情很糟,SQlite有時候只能回退整個當前事務,沒有其他選擇。

  最有可能導致復原的錯誤是SQLITE_FULL(資料庫或磁碟空間已滿),SQLITE_IOERR(磁碟IO錯誤或檔案被鎖定),SQLITE_BUSY(資料庫鎖定),SQLITE_NOMEM(記憶體不足),SQLITE_INTERRUPT(中斷)。如果程式正在執行一個顯示事務,並且收到這些錯誤之一,那就要準備好處理可能將發生的交易回復。

int sqlite3_get_autocommit(sqlite3*);

  通過該函數,可以擷取當前的提交狀態。如果返回非0值,則資料庫處於自動認可(atutoconmit)模式。如果返回0,則資料庫正處於一個顯示事務之中(the database is currently inside an explicit transaction)。

  如果SQlite資料庫被強製做了一次完全交易回復操作,則資料庫將再次變為事務自動認可模式。如果資料庫不在自動認可模式,則它肯定處於一個事務之中,表明並不需要復原。

SQlite資料庫的C編程介面(六)  傳回值和錯誤碼(Result Codes
and Error Codes)  by斜風細雨QQ:253786989    2012-02-07

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.