SQLite3的綁定函數族使用與其注意事項詳解_SQLite

來源:腳本之家  責任編輯:小易  

一.使用流程要使用sqlite,需要從sqlite官網下載到三個文件,分別為sqlite3.lib,sqlite3.dll,sqlite3.h,然后再在自己的工程中配置好頭文件和庫文件,同時將dll文件放到當前目錄下,就完成配置可以使用sqlite了。使用的過程根據使用的函數大致分為如下幾個過程:sqlite3_open()sqlite3_prepare()sqlite3_step()sqlite3_column()sqlite3_finalize()sqlite3_close()這幾個過程是概念上的說法,而不完全是程序運行的過程,如sqlite3_column()表示的是對查詢獲得一行里面的數據的列的各個操作統稱,實際上在sqlite中并不存在這個函數。1.sqlite3_open():打開數據庫在操作數據庫之前,首先要打開數據庫。這個函數打開一個sqlite數據庫文件的連接并且返回一個數據庫連接對象。這個操作同時程序中的第一個調用的 sqlite函數,同時也是其他sqlite api的先決條件。許多的sqlite接口函數都需要一個數據庫連接對象的指針作為它們的第一個參數。函數定義const char*filename,/*Database filename(UTF-8)*/sqlite3*ppDb/*OUT:SQLite db handle*/const void*filename,/*Database filename(UTF-16)*/sqlite3*ppDb/*OUT:SQLite db handle*/const char*filename,/*Database filename(UTF-8)*/sqlite3*ppDb,/*OUT:SQLite db handle*/int flags,/*Flags*/const char*zVfs/*Name of VFS module to use*/說明:假如這個要被打開的數據文件不存在,則一個同名的數據庫文件將被創建。如果使用sqlite3_open和sqlite3_open_v2的話,數據庫將采用UTF-8的編碼方式,sqlite3_open16采用UTF-16的編碼方式返回值:如果sqlite數據庫被成功打開(或創建),將會返回SQLITE_OK,否則將會返回錯誤碼。Sqlite3_errmsg()或者sqlite3_errmsg16可以用于獲得數據庫打開錯誤碼的英文描述,這兩個函數定義為:const char*sqlite3_errmsg(sqlite3*);const void*sqlite3_errmsg16(sqlite3*);參數說明:filename:需要被打開的數據庫文件的文件名,在sqlite3_open和sqlite3_open_v2中這個參數采用UTF-8編碼,而在sqlite3_open16中則采用UTF-16編碼ppDb:一個數據庫連接句柄被返回到這個參數,即使發生錯誤。唯一的一場是如果sqlite不能分配內存來存放sqlite對象,ppDb將會被返回一個NULL值。flags:作為數據庫連接的額外控制的參數,可以是SQLITE_OPEN_READONLY,SQLITE_OPEN_READWRITE和 SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE中的一個,用于控制數據庫的打開方式,可以和SQLITE_OPEN_NOMUTEX,SQLITE_OPEN_FULLMUTEX,SQLITE_OPEN_SHAREDCACHE,以及SQLITE_OPEN_PRIVATECACHE結合使用,具體的詳細情況可以查閱文檔2.Sqlite3_prepare()這個函數將sql文本轉換成一個準備語句(prepared statement)對象,同時返回這個對象的指針。這個接口需要一個數據庫連接指針以及一個要準備的包含SQL語句的文本。它實際上并不執行(evaluate)這個SQL語句,它僅僅為執行準備這個sql語句函數定義(僅列出UTF-8的)sqlite3*db,/*Database handle*/const char*zSql,/*SQL statement,UTF-8 encoded*/int nByte,/*Maximum length of zSql in bytes.*/sqlite3_stmt*ppStmt,/*OUT:Statement handle*/const char*pzTail/*OUT:Pointer to unused portion of zSql*/sqlite3*db,/*Database handle*/const char*zSql,/*SQL statement,UTF-8 encoded*/int nByte,/*Maximum length of zSql in bytes.*/sqlite3_stmt*ppStmt,/*OUT:Statement handle*/const char*pzTail/*OUT:Pointer to unused portion of zSql*/參數:db:數據指針zSql:sql語句,使用UTF-8編碼nByte:如果nByte小于0,則函數取出zSql中從開始到第一個0終止符的內容;如果nByte不是負的,那么它就是這個函數能從zSql中讀取的字節數的最大值。如果nBytes非負,zSql在第一次遇見’/000/或’u000’的時候終止pzTail:上面提到zSql在遇見終止符或者是達到設定的nByte之后結束,假如zSql還有剩余的內容,那么這些剩余的內容被存放到pZTail中,不包括終止符ppStmt:能夠使用sqlite3_step()執行的編譯好的準備語句的指針,如果錯誤發生,它被置為NULL,如假如輸入的文本不包括sql語句。調用過程必須負責在編譯好的sql語句完成使用后使用sqlite3_finalize()刪除它。說明如果執行成功,則返回SQLITE_OK,否則返回一個錯誤碼。推薦在現在任何的程序中都使用sqlite3_prepare_v2這個函數,sqlite3_prepare只是用于前向兼容備注準備語句(prepared statement)對象typedef struct sqlite3_stmt sqlite3_stmt;準備語句(prepared statement)對象一個代表一個簡單SQL語句對象的實例,這個對象通常被稱為“準備語句”或者“編譯好的SQL語句”或者就直接稱為“語句”。語句對象的生命周期經歷這樣的過程:l 使用sqlite3_prepare_v2或相關的函數創建這個對象l 使用sqlite3_bind_*()給宿主參數(host parameters)綁定值l 通過調用sqlite3_step一次或多次來執行這個sqll 使用sqlite3—reset()重置這個語句,然后回到第2步,這個過程做0次或多次l 使用sqlite3_finalize()銷毀這個對象在sqlite中并沒有定義sqlite3_stmt這個結構的具體內容,它只是一個抽象類型,在使用過程中一般以它的指針進行操作,而sqlite3_stmt類型的指針在實際上是一個指向Vdbe的結構體得指針宿主參數(host parameters)在傳給sqlite3_prepare_v2()的sql的語句文本或者它的變量中,滿足如下模板的文字將被替換成一個參數:l?l?NNN,NNN代表數字l:VVV,VVV代表字符[email protected]$VVV在上面這些模板中,NNN代表一個數字,VVV代表一個字母數字標記符(例如:222表示名稱為222的標記符),sql語句中的參數(變量)通過上面的幾個模板來指定,如“select?from?“這個語句中指定了兩個參數,sqlite語句中的第一個參數的索引值是1,這就知道這個語句中的兩個參數的索引分別為1和2,使用”?的話會被自動給 予索引值,而使用”?NNN”則可以自己指定參數的索引值,它表示這個參數的索引值為NNN。VVV”表示一個名為”VVV”的參數,它也有一個索引 值,被自動指定。可以使用sqlite3_bind_*()來給這些參數綁定值3.sqlite3_setp()這個過程用于執行有前面sqlite3_prepare創建的準備語句。這個語句執行到結果的第一行可用的位置。繼續前進到結果的第二行的話,只需再次調 用sqlite3_setp()。繼續調用sqlite3_setp()知道這個語句完成,那些不返回結果的語句(如:INSERT,UPDATE,或 DELETE),sqlite3_step()只執行一次就返回函數定義int sqlite3_step(sqlite3_stmt*);返回值函數的返回值基于創建sqlite3_stmt參數所使用的函數,假如是使用老版本的接口sqlite3_prepare()和 sqlite3_prepare16(),返回值會 是 SQLITE_BUSY,SQLITE_DONE,SQLITE_ROW,SQLITE_ERROR 或 SQLITE_MISUSE,而v2版本的接口sqlite3_prepare_v2()和sqlite3_prepare16_v2()則會同時返 回這些結果碼和擴展結果碼。對所有V3.6.23.1以及其前面的所有版本,需要在sqlite3_step()之后調用sqlite3_reset(),在后續的sqlite3_step之前。如果調用sqlite3_reset重置準備語句失敗,將會導致sqlite3_step返回SQLITE_MISUSE,但是在V3.6.23.1以后,sqlite3_step()將會自動調用sqlite3_reset。int sqlite3_reset(sqlite3_stmt*pStmt);sqlite3_reset用于重置一個準備語句對象到它的初始狀態,然后準備被重新執行。所有sql語句變量使用sqlite3_bind*綁定值,使 用sqlite3_clear_bindings重設這些綁定。Sqlite3_reset接口重置準備語句到它代碼開始的時候。sqlite3_reset并不改變在準備語句上的任何綁定值,那么這里猜測,可能是語句在被執行的過程中發生了其他的改變,然后這個語句將它重置到綁定值的時候的那個狀態。4.sqlite3_column()這個過程從執行sqlite3_step()執行一個準備語句得到的結果集的當前行中返回一個列。每次sqlite3_step得到一個結果集的列停下后,這個過程就可以被多次調用去查詢這個行的各列的值。對列操作是有多個函數,均以sqlite3_column為前綴const void*sqlite3_column_blob(sqlite3_stmt*,int iCol);int sqlite3_column_bytes(sqlite3_stmt*,int iCol);int sqlite3_column_bytes16(sqlite3_stmt*,int iCol);double sqlite3_column_double(sqlite3_stmt*,int iCol);int sqlite3_column_int(sqlite3_stmt*,int iCol);sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*,int iCol);const unsigned char*sqlite3_column_text(sqlite3_stmt*,int iCol);const void*sqlite3_column_text16(sqlite3_stmt*,int iCol);int sqlite3_column_type(sqlite3_stmt*,int iCol);sqlite3_value*sqlite3_column_value(sqlite3_stmt*,int iCol);www.13333515.buzz防采集請勿采集本網。

前言

本文給大家展示的代碼實際上就是如何利用Sqlite3的參數化機制做數據插入,也可以update操作,就看你怎么玩了,這里只列出代碼,然后說一些注意事項。

Sqlite默認保存數據是用UTF8格式,而現有程序開發工具都是默認GB2312的格式,所以你編程寫的中文不轉碼直接寫到庫里后,用任何數據庫工具看肯定都是亂碼。但是讀出來之后仍然是GB2312,所以顯示正常。反之

下面的代碼,有一個問題,插入后的東西一定是:

@Override 根據—_id篩選數據*/ public User Select(String id){ Cursor cursor=db.rawQuery(\"SELECT*FROM user WHERE_id=?and name=?這里可以添加篩選條件 new String[]{ id });if(cursor.

INSERT INTO "work" VALUES('鉿','鉿鉿鉿鉿鉿',NULL,NULL,NULL,NULL,'鉿鉿鉿鉿鉿',NULL,NULL,110.0,1.0,108.9,NULL,NULL,'鉿鉿鉿鉿鉿',NULL,NULL,NULL,'鉿鉿鉿鉿鉿',NULL,NULL,NULL);

sqlite3 提供了各種語言的 API 綁定,C 語言的當然也有,具體參考 https://www.sqlite.org/capi3ref.html

看看有問題的代碼:

sqlite3 的源碼,好像是 sqlite3.h sqlite3_ext.h 以及 sqlite3.cc 可以將源碼編譯成庫(靜態庫或者動態庫),或者直接嵌入到工程中參與編譯 數據庫操作的一般流程是: sqlite3_open()/sqlite3_open_

sqlite3_stmt *stmt; CString sql = "insert into work values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL); if(rc != SQLITE_OK) { MessageBox("sqlite3_prepare_v2 Failed!"); return; } count = 0; p_wnd = PrevWnd; while(count++ < ID_TOTALCOUNT) { CString DbStr; p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE); if(p_wnd == NULL) { return; } p_wnd->GetWindowText(DbStr); do { if(!DbStr.GetLength()) { rc = sqlite3_bind_null(stmt, count); break; } //日期相關 if( count == ID_CHUDANRIQI || count == ID_CHUFARIQI || count == ID_HUANKUANRIQI || count == ID_HUOLIRIQI) { CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd; CString time = DateTimeToString(*TimeCtl); rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC); break; } else { //金錢相關的處理real類型 if( count == ID_BAOXIANJINE || count == ID_YONGJINBILV || count == ID_JINGBAOFEI || count == ID_HUANKUANJINE || count == ID_LIRUNBILV || count == ID_LIRUNJINE) { double tMoney = 0.0; int rtn = sscanf_s(DbStr.GetString(), "%lf", &tMoney); ASSERT(rtn == 1); rc = sqlite3_bind_double(stmt, count, tMoney); } else { char *str = (char *)DbStr.GetString(); int c = strlen(str); int c1 = DbStr.GetLength(); rc = sqlite3_bind_text(stmt, count, DbStr.GetString(), -1/*DbStr.GetLength()*/, SQLITE_STATIC); } } }while(0); if(rc != SQLITE_OK) { CString ErrStr = sqlite3_errstr(rc); MessageBox(ErrStr); return; } } rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) { if(rc == SQLITE_ERROR) { CString DbErr; DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db)); MessageBox(DbErr); } else { MessageBox("sqlite3_step Failed!"); } } sqlite3_finalize(stmt);

Sqlite v三數據庫任何列除整形主鍵列用于存儲任何存儲列值sql語句所值管嵌入sql文本或者作參數綁定預編譯sql語句存儲類型都未定面描述情況數據庫引擎查詢執行程數值(numeric)存儲類型

為什么呢?

因為,sqlite3_bind_text綁定的text,需要在做:

rc = sqlite3_step(stmt);

的時候統一提交,而上面的代碼使用的臨時變量,rc = sqlite3_step(stmt);的時候,早就不存在了。因此亂碼也是正常的。

修改如下:

sqlite3_stmt *stmt; CString sql = "insert into work values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; int rc = sqlite3_prepare_v2(db, sql.GetString(), -1, &stmt, NULL); if(rc != SQLITE_OK) { MessageBox("sqlite3_prepare_v2 Failed!"); return; } count = 0; p_wnd = PrevWnd; CString DbStr[ID_TOTALCOUNT + 1]; while(count++ < ID_TOTALCOUNT) { DbStr[count].Empty(); p_wnd = CWnd::GetNextDlgTabItem(p_wnd, FALSE); if(p_wnd == NULL) { return; } p_wnd->GetWindowText(DbStr[count]); do { if(!DbStr[count].GetLength()) { rc = sqlite3_bind_null(stmt, count); break; } //日期相關 if( count == ID_CHUDANRIQI || count == ID_CHUFARIQI || count == ID_HUANKUANRIQI || count == ID_HUOLIRIQI) { CDateTimeCtrl *TimeCtl = (CDateTimeCtrl *)p_wnd; CString time = DateTimeToString(*TimeCtl); DbStr[count] = time; rc = sqlite3_bind_text(stmt, count, time.GetString(), time.GetLength(), SQLITE_STATIC); } else { //金錢相關的處理real類型 if( count == ID_BAOXIANJINE || count == ID_YONGJINBILV || count == ID_JINGBAOFEI || count == ID_HUANKUANJINE || count == ID_LIRUNBILV || count == ID_LIRUNJINE) { double tMoney = 0.0; int rtn = sscanf_s(DbStr[count].GetString(), "%lf", &tMoney); ASSERT(rtn == 1); rc = sqlite3_bind_double(stmt, count, tMoney); } else { rc = sqlite3_bind_text(stmt, count, DbStr[count].GetString(), DbStr[count].GetLength(), SQLITE_STATIC); } } }while(0); if(rc != SQLITE_OK) { CString ErrStr = sqlite3_errstr(rc); MessageBox(ErrStr); return; } } rc = sqlite3_step(stmt); if(rc != SQLITE_DONE) { if(rc == SQLITE_ERROR) { CString DbErr; DbErr.Format("Sql Insert failed, %s", sqlite3_errmsg(db)); MessageBox(DbErr); } else { MessageBox("sqlite3_step Failed!"); } } sqlite3_finalize(stmt);

附上數據庫創建的sql語法:

sqlite> .dump workPRAGMA foreign_keys=OFF;BEGIN TRANSACTION;CREATE TABLE work (baodanhao text unique primary key , chudanriqi text,qudao text,lianxiren text,xiaoshou text,beibaorenxingming text,chufariqi text,baoxianpinpai text,baoxianjihua text,baoxianjine real,yongjinbilv real,jingbaofei real,huankuanfangshi text,haikuanjine real,huankuanriqi text,shifouquane text,lirunbilv real,lirunjine real,huoliriqi text,fapiaojisong text,shifubaoxiangongsi text,beizhu text);

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對真格學網的支持。

[DCC Error]Unit1.pas(57):E2003 Undeclared identifier:'OpenDialog1'[DCC Error]Unit1.pas(57):E2066 Missing operator or semicolon[DCC Error]Unit1.pas(58):E2029 'THEN' expected but identifier 'Execute' found[DCC Fatal Error]Project1.dpr(5):F2063 Could not compile used unit 'Unit1.pas'答題不易,互相幫助,手機提問的朋友在客戶端右上角評價點滿意即可.如認可我的回答,請點擊采納為滿意回答按鈕內容來自www.13333515.buzz請勿采集。


  • 本文相關:
  • sqlite3中的日期時間函數使用小結
  • 為sqlite3提供一個ansi到utf8的互轉函數
  • 初識sqlite3數據庫
  • sqlite數據庫管理系統-我所認識的數據庫引擎
  • sqlite3 top的查詢及limit語法介紹
  • sqlite 入門教程三 好多約束 constraints
  • sqlite教程(十三):c語言編程實例代碼(1)
  • sqlite 常用函數 推薦
  • sqlite中重置自動編號列的方法
  • sqlite 入門教程一 基本控制臺(終端)命令
  • sqlite教程(九):在線備份
  • sqlite 錯誤碼整理
  • sqlite3查詢也需要綁定嗎
  • sqlite3 數據庫 最大支持多少條數據
  • 如何調用sqlite3.dll
  • sqlite3 字段數據類型怎么看
  • linux中sqlite3 參數綁定怎么解決亂碼
  • Listview怎么綁定SQLite數據庫?
  • 如何在Linux下用C/C++語言操作數據庫sqlite3
  • 如何在Linux下用C語言操作數據庫sqlite3.pdf
  • sqlite 字段設置什么類型
  • 在linux c 下怎樣向sqlite數據庫表中插入滿足下面條件的數據啊?
  • 網站首頁網頁制作腳本下載服務器操作系統網站運營平面設計媒體動畫電腦基礎硬件教程網絡安全mssqlmysqlmariadboracledb2mssql2008mssql2005sqlitepostgresqlmongodbredisaccess數據庫文摘數據庫其它首頁sqlitesqlite3中的日期時間函數使用小結為sqlite3提供一個ansi到utf8的互轉函數初識sqlite3數據庫sqlite數據庫管理系統-我所認識的數據庫引擎sqlite3 top的查詢及limit語法介紹sqlite 入門教程三 好多約束 constraintssqlite教程(十三):c語言編程實例代碼(1)sqlite 常用函數 推薦sqlite中重置自動編號列的方法sqlite 入門教程一 基本控制臺(終端)命令sqlite教程(九):在線備份sqlite 錯誤碼整理sqlite中文亂碼問題原因分析及解sqlite3中的日期時間函數使用小結sqlite3 top的查詢及limit語法介linux sqlite3 基本命令sqlite 錯誤碼整理sqlite3中自增主鍵相關知識總結sqlite優化方法sqlite循環批量插入數據采用批處sqlite3 使用總結sqlite 常用函數 推薦一些很有用的sqlite命令總結sqlite教程(十二):鎖和并發控制詳解sqlite教程(二):c/c++接口簡介sqlite 操作類代碼sqlite 入門教程三 好多約束 constraints初識sqlite3數據庫sqlite中的wal機制詳細介紹sqlite 內存數據庫學習手冊sqlite中文亂碼問題原因分析及解決sqlite 入門教程四 增刪改查 有講究
    免責聲明 - 關于我們 - 聯系我們 - 廣告聯系 - 友情鏈接 - 幫助中心 - 頻道導航
    Copyright © 2017 www.13333515.buzz All Rights Reserved
    3排列五开奖结果