⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 execute.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Module:          execute.c * * Description:     This module contains routines related to  *                  preparing and executing an SQL statement. * * Classes:         n/a * * API functions:   SQLPrepare, SQLExecute, SQLExecDirect, SQLTransact, *                  SQLCancel, SQLNativeSql, SQLParamData, SQLPutData * * Comments:        See "notice.txt" for copyright and license information. * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "psqlodbc.h"#include <stdio.h>#include <string.h>#ifndef WIN32#include "iodbc.h"#include "isqlext.h"#else#include <windows.h>#include <sqlext.h>#endif#include "connection.h"#include "statement.h"#include "qresult.h"#include "convert.h"#include "bind.h"#include "lobj.h"extern GLOBAL_VALUES globals;//      Perform a Prepare on the SQL statementRETCODE SQL_API SQLPrepare(HSTMT     hstmt,                           UCHAR FAR *szSqlStr,                           SDWORD    cbSqlStr){static char *func = "SQLPrepare";StatementClass *self = (StatementClass *) hstmt;	mylog( "%s: entering...\n", func);	if ( ! self) {		SC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}    	/*	According to the ODBC specs it is valid to call SQLPrepare mulitple times.		In that case, the bound SQL statement is replaced by the new one 	*/	switch(self->status) {	case STMT_PREMATURE:		mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n");		SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */		break;	case STMT_FINISHED:		mylog("**** SQLPrepare: STMT_FINISHED, recycle\n");		SC_recycle_statement(self); /* recycle the statement, but do not remove parameter bindings */		break;	case STMT_ALLOCATED:		mylog("**** SQLPrepare: STMT_ALLOCATED, copy\n");		self->status = STMT_READY;		break;	case STMT_READY:		mylog("**** SQLPrepare: STMT_READY, change SQL\n");		break;	case STMT_EXECUTING:		mylog("**** SQLPrepare: STMT_EXECUTING, error!\n");		self->errornumber = STMT_SEQUENCE_ERROR;		self->errormsg = "SQLPrepare(): The handle does not point to a statement that is ready to be executed";		SC_log_error(func, "", self);		return SQL_ERROR;	default:		self->errornumber = STMT_INTERNAL_ERROR;		self->errormsg = "An Internal Error has occured -- Unknown statement status.";		SC_log_error(func, "", self);		return SQL_ERROR;	}	if (self->statement)		free(self->statement);	self->statement = make_string(szSqlStr, cbSqlStr, NULL);	if ( ! self->statement) {		self->errornumber = STMT_NO_MEMORY_ERROR;		self->errormsg = "No memory available to store statement";		SC_log_error(func, "", self);		return SQL_ERROR;	}	self->prepare = TRUE;	self->statement_type = statement_type(self->statement);	//	Check if connection is readonly (only selects are allowed)	if ( CC_is_readonly(self->hdbc) && STMT_UPDATE(self)) {		self->errornumber = STMT_EXEC_ERROR;		self->errormsg = "Connection is readonly, only select statements are allowed.";		SC_log_error(func, "", self);		return SQL_ERROR;	}	return SQL_SUCCESS;}//      -       -       -       -       -       -       -       -       -//      Performs the equivalent of SQLPrepare, followed by SQLExecute.RETCODE SQL_API SQLExecDirect(        HSTMT     hstmt,        UCHAR FAR *szSqlStr,        SDWORD    cbSqlStr){StatementClass *stmt = (StatementClass *) hstmt;RETCODE result;static char *func = "SQLExecDirect";	mylog( "%s: entering...\n", func);    	if ( ! stmt) {		SC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	if (stmt->statement)		free(stmt->statement);	// keep a copy of the un-parametrized statement, in case	// they try to execute this statement again	stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);	if ( ! stmt->statement) {		stmt->errornumber = STMT_NO_MEMORY_ERROR;		stmt->errormsg = "No memory available to store statement";		SC_log_error(func, "", stmt);		return SQL_ERROR;	}	mylog("**** %s: hstmt=%u, statement='%s'\n", func, hstmt, stmt->statement);	stmt->prepare = FALSE;	stmt->statement_type = statement_type(stmt->statement);	//	Check if connection is readonly (only selects are allowed)	if ( CC_is_readonly(stmt->hdbc) && STMT_UPDATE(stmt)) {		stmt->errornumber = STMT_EXEC_ERROR;		stmt->errormsg = "Connection is readonly, only select statements are allowed.";		SC_log_error(func, "", stmt);		return SQL_ERROR;	}		mylog("%s: calling SQLExecute...\n", func);	result = SQLExecute(hstmt);	mylog("%s: returned %hd from SQLExecute\n", func, result);	return result;}//      Execute a prepared SQL statementRETCODE SQL_API SQLExecute(        HSTMT   hstmt){static char *func="SQLExecute";StatementClass *stmt = (StatementClass *) hstmt;ConnectionClass *conn;int i, retval;	mylog("%s: entering...\n", func);	if ( ! stmt) {		SC_log_error(func, "", NULL);		mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func);		return SQL_INVALID_HANDLE;	}	/*  If the statement is premature, it means we already executed		it from an SQLPrepare/SQLDescribeCol type of scenario.  So		just return success.	*/	if ( stmt->prepare && stmt->status == STMT_PREMATURE) {		stmt->status = STMT_FINISHED;       		if (stmt->errormsg == NULL) {			mylog("%s: premature statement but return SQL_SUCCESS\n", func);			return SQL_SUCCESS;		}		else {			SC_log_error(func, "", stmt);			mylog("%s: premature statement so return SQL_ERROR\n", func);			return SQL_ERROR;		}	}  	mylog("%s: clear errors...\n", func);	SC_clear_error(stmt);	conn = SC_get_conn(stmt);	if (conn->status == CONN_EXECUTING) {		stmt->errormsg = "Connection is already in use.";		stmt->errornumber = STMT_SEQUENCE_ERROR;		SC_log_error(func, "", stmt);		mylog("%s: problem with connection\n", func);		return SQL_ERROR;	}	if ( ! stmt->statement) {		stmt->errornumber = STMT_NO_STMTSTRING;		stmt->errormsg = "This handle does not have a SQL statement stored in it";		SC_log_error(func, "", stmt);		mylog("%s: problem with handle\n", func);		return SQL_ERROR;	}	/*	If SQLExecute is being called again, recycle the statement.		Note this should have been done by the application in a call		to SQLFreeStmt(SQL_CLOSE) or SQLCancel.	*/	if (stmt->status == STMT_FINISHED) {		mylog("%s: recycling statement (should have been done by app)...\n", func);		SC_recycle_statement(stmt);	}	/*	Check if the statement is in the correct state */	if ((stmt->prepare && stmt->status != STMT_READY) || 		(stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) {				stmt->errornumber = STMT_STATUS_ERROR;		stmt->errormsg = "The handle does not point to a statement that is ready to be executed";		SC_log_error(func, "", stmt);		mylog("%s: problem with statement\n", func);		return SQL_ERROR;	}	/*	The bound parameters could have possibly changed since the last execute		of this statement?  Therefore check for params and re-copy.	*/	stmt->data_at_exec = -1;	for (i = 0; i < stmt->parameters_allocated; i++) {		/*	Check for data at execution parameters */		if ( stmt->parameters[i].data_at_exec == TRUE) {			if (stmt->data_at_exec < 0)				stmt->data_at_exec = 1;			else				stmt->data_at_exec++;		}	}	//	If there are some data at execution parameters, return need data	//	SQLParamData and SQLPutData will be used to send params and execute the statement.	if (stmt->data_at_exec > 0)		return SQL_NEED_DATA;	mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement);	//	Create the statement with parameters substituted.	retval = copy_statement_with_parameters(stmt);	if( retval != SQL_SUCCESS)		/* error msg passed from above */		return retval;	mylog("   stmt_with_params = '%s'\n", stmt->stmt_with_params);	return SC_execute(stmt);}//      -       -       -       -       -       -       -       -       -RETCODE SQL_API SQLTransact(        HENV    henv,        HDBC    hdbc,        UWORD   fType){static char *func = "SQLTransact";extern ConnectionClass *conns[];ConnectionClass *conn;QResultClass *res;char ok, *stmt_string;int lf;	mylog("entering %s: hdbc=%u, henv=%u\n", func, hdbc, henv);	if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) {		CC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	/* If hdbc is null and henv is valid,	it means transact all connections on that henv.  	*/	if (hdbc == SQL_NULL_HDBC && henv != SQL_NULL_HENV) {		for (lf=0; lf <MAX_CONNECTIONS; lf++) {			conn = conns[lf];			if (conn && conn->henv == henv)				if ( SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS)					return SQL_ERROR;		}		return SQL_SUCCESS;       	}	conn = (ConnectionClass *) hdbc;	if (fType == SQL_COMMIT) {		stmt_string = "COMMIT";	} else if (fType == SQL_ROLLBACK) {		stmt_string = "ROLLBACK";	} else {		conn->errornumber = CONN_INVALID_ARGUMENT_NO;		conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";		CC_log_error(func, "", conn);		return SQL_ERROR;	}    	/*	If manual commit and in transaction, then proceed. */	if ( ! CC_is_in_autocommit(conn) &&  CC_is_in_trans(conn)) {		mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string);		res = CC_send_query(conn, stmt_string, NULL);		CC_set_no_trans(conn);		if ( ! res) {			//	error msg will be in the connection			CC_log_error(func, "", conn);			return SQL_ERROR;		}		ok = QR_command_successful(res);   		QR_Destructor(res);		if (!ok) {			CC_log_error(func, "", conn);			return SQL_ERROR;		}	}    	return SQL_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -