描述
运行零个或多个UTF-8编码,分号分隔的SQL语句。
sqlite3_exec功能是围绕sqlite3_prepare_v2sqlite3_step和sqlite3_finalize的便利包装器,允许应用程序运行多个SQL语句,而无需使用大量代码。
C / C ++语法
int sqlite3_exec( sqlite3*, const char *sql, int (*callback)(void*,int,char**,char**), char **errmsg ); |
PB语法
FUNCTION sqlite3_exec ( _ BYVAL hDbc AS DWORD, _ BYREF szSql AS ASCIIZ, _ BYVAL pCallback AS DWORD, _ BYVAL pData AS DWORD, _ BYREF errmsg AS DWORD _ ) AS LONG |
参数
pDb
[in]数据库连接句柄。必须是从sqlite3_opensqlite3_open16或sqlite3_open_v2获取的sqlite3对象指针。 应用程序必须确保此参数是有效和打开的数据库连接。当sqlite3_exec运行时,应用程序不得关闭此参数指定的数据库连接。
szSql
[in]一个或多个UTF-8编码,分号分隔的SQL语句。当运行sqlite3_exec时,应用程序不得修改传递给此参数的SQL语句文本。
pCallback
[in]指向回调函数的指针。如果不为NULL,则从评估的SQL语句中输出的每个结果行调用回调函数。如果为NULL,则不会调用回调,并忽略结果行。
pData
[in]一个可选值,被转发到每个回调调用的第一个参数。
errmsg
[in]如果不为NULL,任何错误消息都将写入从sqlite3_malloc获取并传回的内存中。为避免内存泄漏,应用程序应该在不再需要错误消息字符串后调用返回的错误消息字符串sqlite3_free.如果此参数不为NULL并且没有发生错误,则sqlite3_exec将返回前将指针设置为NULL。
返回值
如果成功返回SQLITE_OK,否则返回错误代码。
备注
回调函数原型:
typedef int (*sqlite3_callback)(void*,int,char**, char**);
FUNCTION SQLite_Exec_Callback CDECL ( _
BYVAL pData AS DWORD, _
BYVAL numCols AS LONG, _
BYVAL pszColValues AS ASCIIZ PTR, _
BYVAL pszColNames AS ASCIIZ PTR _
) AS LONG
pData
[in]sqlite3_exec的pUserData参数中传递的值。
numCols
[in]结果中的列数。
pColValues
[in]指向字符串数组的指针,如从sqlite3_column_text获得的,每列一个。如果结果行的元素为空,那么sqlite3_exec回调的相应字符串指针是空指针。
pColNames
[in]指针指向字符串的指针数组,其中每个条目表示从sqlite3_column_name获取的相应结果列的名称。
返回值
如果sqlite3_exec回调返回非零,则sqlite3_exec函数返回SQLITE_ABORT,而不再调用回调,而不运行任何后续SQL语句。
用于检索pColValues和pColNames数组的内容的用法示例:
FOR i = 0 TO numCols - 1
? "Column name: " & @@pszColNames[i]
? "Column value: " & @@pszColVals[i]
NEXT
C ++实现代码
/*
** Execute SQL code. Return one of the SQLITE_ success/failure
** codes. Also write an error message into memory obtained from
** malloc() and make *pzErrMsg point to that message.
**
** If the SQL is a query, then for each row in the query result
** the xCallback() function is called. pArg becomes the first
** argument to xCallback(). If xCallback=NULL then no callback
** is invoked, even for queries.
*/
SQLITE_API int sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
sqlite3_callback xCallback, /* Invoke this callback function */
void *pArg, /* First argument to xCallback() */
char **pzErrMsg /* Write error messages here */
){
int rc = SQLITE_OK; /* Return code */
const char *zLeftover; /* Tail of unprocessed SQL */
sqlite3_stmt *pStmt = 0; /* The current SQL statement */
char **azCols = 0; /* Names of result columns */
int nRetry = 0; /* Number of retry attempts */
int callbackIsInit; /* True if callback data is initialized */
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
if( zSql==0 ) zSql = "";
sqlite3_mutex_enter(db->mutex);
sqlite3Error(db, SQLITE_OK, 0);
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
int nCol;
char **azVals = 0;
pStmt = 0;
rc = sqlite3_prepare(db, zSql, -1, &pStmt, &zLeftover);
assert( rc==SQLITE_OK || pStmt==0 );
if( rc!=SQLITE_OK ){
continue;
}
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
continue;
}
callbackIsInit = 0;
nCol = sqlite3_column_count(pStmt);
while( 1 ){
int i;
rc = sqlite3_step(pStmt);
/* Invoke the callback function if required */
if( xCallback && (SQLITE_ROW==rc ||
(SQLITE_DONE==rc && !callbackIsInit
&& db->flags&SQLITE_NullCallback)) ){
if( !callbackIsInit ){
azCols = sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1);
if( azCols==0 ){
goto exec_out;
}
for(i=0; i<nCol; i++){
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
/* sqlite3VdbeSetColName() installs column names as UTF8
** strings so there is no way for sqlite3_column_name() to fail. */
assert( azCols[i]!=0 );
}
callbackIsInit = 1;
}
if( rc==SQLITE_ROW ){
azVals = &azCols[nCol];
for(i=0; i<nCol; i++){
azVals[i] = (char *)sqlite3_column_text(pStmt, i);
if( !azVals[i] && sqlite3_column_type(pStmt, i)!=SQLITE_NULL ){
db->mallocFailed = 1;
goto exec_out;
}
}
}
if( xCallback(pArg, nCol, azVals, azCols) ){
rc = SQLITE_ABORT;
sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
sqlite3Error(db, SQLITE_ABORT, 0);
goto exec_out;
}
}
if( rc!=SQLITE_ROW ){
rc = sqlite3VdbeFinalize((Vdbe *)pStmt);
pStmt = 0;
if( rc!=SQLITE_SCHEMA ){
nRetry = 0;
zSql = zLeftover;
while( sqlite3Isspace(zSql[0]) ) zSql++;
}
break;
}
}
sqlite3DbFree(db, azCols);
azCols = 0;
}
exec_out:
if( pStmt ) sqlite3VdbeFinalize((Vdbe *)pStmt);
sqlite3DbFree(db, azCols);
rc = sqlite3ApiExit(db, rc);
if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
*pzErrMsg = sqlite3Malloc(nErrMsg);
if( *pzErrMsg ){
memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
}else{
rc = SQLITE_NOMEM;
sqlite3Error(db, SQLITE_NOMEM, 0);
}
}else if( pzErrMsg ){
*pzErrMsg = 0;
}
assert( (rc&db->errMask)==rc );
sqlite3_mutex_leave(db->mutex);
return rc;
}