构造和执行SQL语句
构造SQL语句
可以通过三种方式构造SQL语句:在程序开发阶段确定、在运行时确定或由用户输入SQL语句。
在程序开发时确定的SQL语句,具有易于实现、且可在程序编码时进行测试的优势。
在程序运行时确定SQL语句提供了极大灵活性,但给程序高度带来了困难,且需更多的处理时间。由用户输入的SQL语句,极大的增强了程序的功能,但是,程序必须提供友好的人机界面,且对用户输入的语句执行一定程序的语法检查,能够报告用户错误。
执行SQL语句
应用程序的绝大部分数据库访问工作都是通过执行SQL语句完成的,在执行SQL语句之前,必须要先分配一个语句句柄,然后设置相应语句的语句属性,再执行SQL语句。当一个语句句柄使用完成后,调用函数SQLFreeHandle()释放该句柄。
SQLExecute()
SQLExecute用于执行一个准备好的语然,当语句中有参数时,用当前绑定的参数变量的值。
函数格式:
SQLRETURN SQLExecute(SQLHSTMT StatementHandle);
参数:
StatementHandle 标识执行SQL语句的句柄,可以用SQLAllocHandle()来获得。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
SQLExecDiret()
SQLExecDirect直接执行SQL语句,对于只执行一次的操作来说,该函数是速度最快的方法。
函数格式:
SQLRETURN SQLExecDirect(SQLHSTMT StatementHandle,SQLCHAR *StatementText,SQLINTEGER TextLength);
参数:
StatementHandle 语句句柄
StatementText 要执行的SQL语然
StatementText SQL语句的长度。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
SQLPripare()
对于需多次执行的SQL语句来说,除了使用SQLExecDirect函数之外,我们也可以在执行SQL语句之前,先准备SQL语句的执行。对于使用参数的语句,这可大提高程序执行速度。
函数格式:
SQLRETURN SQLPrepare(SQLHSTMT StatementHandle,SQLCHAR* StatementText,SQLINTEGER TextLength);
参数:
StatementHandle 语句句柄
StatementText 要执行的SQL语然
StatementText SQL语句的长度。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_NEED_DATA, SQL_STILL_EXECUTING, SQL_ERROR, SQL_NO_DATA, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
使用参数
使用参数可以使一条SQL语句多次执行,得到不同结果
SQLBindParameter
函数SQLBindParameter负责为参数定义变量,实现参数值的传递。
函数格式如下:
SQLRETURNSQLBindParameter(SQLHSTMT StatementHandle,SQLUSMALLINT ParameterNumber,SQLSMALLINT InputOutputType,SQLSMALLINT ValueType,SQLSMALLINT ParameterType,SQLUINTEGER ColumnSize,SQLSMALLINT DecimalDigits,SQLPOINTER ParameterValuePtr,SQLINTEGER BufferLength,SQLINTEGER *StrLen_or_IndPtr);
参数:
StatementHandle 语句句柄
ParameterNumber 绑定的参数在SQL语句中的序号,在SQL中,所有参数从左到右顺序编号,从1开始。SQL语句执行之前,应该为每个参数调用函数SQLBindParameter绑定到某个程序变量。
InputOutputType 参数类型,可为SQL_PARA_INPUT, SQL_PARAM_INPUT_OUTPUT, SQL_PARAM_OUTPUT。
ParameterType 参数数据类型
ColumnSIze 参数大小
DecimalDigits 参数精度
ParameterValutePtr 指向程序中存放参数值的缓冲区的指针
BufferLength 程序中存放参数值的缓冲区的字节数
StrLen_or_IndPtr 指向存放参数ParameterValuePtr的缓冲区指针
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
执行时传递参数
对于某些文本文档或位图文件,要占用大量的存储空间。因此,在数据源传递这些数据时,可以分开传递。有两个函数可完成这个工作。
函数格式:
SQLRETURN SQLPutData(SQLHSTMT StatementHandle,SQLPOINTER DataPtr,SQLINTEGER StrLen_or_Ind);
参数:
StatementHandle 参数句柄
DataPtr 指向包含实际数据的缓冲区指针。
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
函数格式:
SQLRETURNSQLParamData(SQLHSTMT StatementHandle,SQLPOINTER *ValuePtrPtr);
参数:
StatementHandle 参数句柄
ValuePtrPtr 指向缓冲区地址的指针
返回值:
SQL_SUCCESS, SQL_SUCCESS_WITH_INFO, SQL_ERROR, or SQL_INVALID_HANDLE
成功返回SQL_SUCCESS,如果返回值为SQL_ERROR或SQL_SUCCESS_WITH_INFO,可以用函数SQLGetDiagRec获取相应SQLSTATE的值。
下面的代码展示如何使用这两个函数
| #define MAX_DATA_LEN 1024 SQLINTEGER cbPartID = 0, cbPhotoParam, cbData; SQLUINTEGER sPartID; szPhotoFile; SQLPOINTER pToken, InitValue; SQLCHAR Data[MAX_DATA_LEN]; SQLRETURN retcode; SQLHSTMT hstmt; retcode = SQLPrepare(hstmt, "INSERT INTO PICTURES (PARTID, PICTURE) VALUES ( , )", SQL_NTS); if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) { /* Bind the parameters. For parameter 2, pass */ /* the parameter number in ParameterValuePtr instead of a buffer */ /* address. */ SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &sPartID, 0, &cbPartID); SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 2, 0, &cbPhotoParam); /* Set values so data for parameter 2 will be */ /* passed at execution. Note that the length parameter in */ /* the macro SQL_LEN_DATA_AT_EXEC is 0. This assumes that */ /* the driver returns "N" for the SQL_NEED_LONG_DATA_LEN */ /* information type in SQLGetInfo. */ cbPhotoParam = SQL_LEN_DATA_AT_EXEC(0); sPartID = GetNextID(); /* Get next available employee ID */ /* number. */ retcode = SQLExecute(hstmt); /* For data-at-execution parameters, call SQLParamData to */ /* get the parameter number set by SQLBindParameter. */ /* Call InitUserData. Call GetUserData and SQLPutData */ /* repeatedly to get and put all data for the parameter. */ /* Call SQLParamData to finish processing this parameter */ while (retcode == SQL_NEED_DATA) { retcode = SQLParamData(hstmt, &pToken); if (retcode == SQL_NEED_DATA) { InitUserData((SQLSMALLINT)pToken, InitValue); while (GetUserData(InitValue, (SQLSMALLINT)pToken, Data, &cbData)) SQLPutData(hstmt, Data, cbData); } }} VOID InitUserData(sParam, InitValue)SQLPOINTER InitValue;{ SQLCHAR szPhotoFile[MAX_FILE_NAME_LEN]; /* Prompt user for bitmap file containing employee */ /* photo. OpenPhotoFile opens the file and returns the */ /* file handle. */ PromptPhotoFileName(szPhotoFile); OpenPhotoFile(szPhotoFile, (FILE *)InitValue); break; } BOOL GetUserData(InitValue, sParam, Data, cbData)SQLPOINTER InitValue; SQLCHAR *Data;SQLINTEGER *cbData;BOOL Done;{ /* GetNextPhotoData returns the next piece of photo */ /* data and the number of bytes of data returned */ /* (up to MAX_DATA_LEN). */ Done = GetNextPhotoData((FILE *)InitValue, Data, MAX_DATA_LEN, &cbData); if (Done) { ClosePhotoFile((FILE *)InitValue); return (TRUE); } return (FALSE); } |