WIN32汇编实现基于API的ODBC编程

来源(cloudandy的专栏 - CSDN博客)

From: http://blog.csdn.net/cloudandy/archive/2008/11/14/3298046.aspx

m2m macro p1,p2
 push p2
 pop p1
endm

.data

szBuffer db 256 dup(0)
szFormat db '%d',0dh,0ah,0


Connection struct
 hEnv      dword 0 ;建立的环境的句柄
 hConn      dword 0 ;建立的连接的句柄
 pInConnectString    dword 0 ;输入的连接字符串缓冲区的指针
 inConnectStringLength  dword 0 ;输入的连接字符串缓冲区的长度
 pOutConnStr     dword 0 ;输出的连接字符串缓冲区的指针
 outConnStrLength   dword 0 ;输出的连接字符串缓冲区的长度
 pOutConnStrLength   dword 0 ;输出的连接字符串的实际长度
Connection ends

Parameter struct
 pParamValue    dword 0 ;参数缓冲区的指针
 pParamStrL    dword 0 ;参数缓冲区的实际长度的指针
 paramStrL    dword 0 ;参数缓冲区的实际长度
 paramValueSize   dword 0 ;对应的参数的数据库中的长度
 paramType    dword 0 ;参数对应的C类型
 paramDirection   dword 0 ;参数的输入输出类型(INPUT,OUTPUT,INPUT_OUTPUT)
 paramDType    dword 0 ;数据库中对应的参数的类型
 paramDSize    dword 0 ;数据库中对应的参数的长度
 paramDeimalSize   dword  0 ;数据库中对应的参数的DEIMAL长度

Parameter ends

.code

DEBUG proc val:dword

 invoke wsprintf,addr szBuffer,addr szFormat,val
 invoke MessageBox,NULL,addr szBuffer,NULL,MB_OK

 ret
DEBUG endp

DEBUG2 proc pval:dword


 invoke MessageBox,NULL,pval,NULL,MB_OK

 ret
DEBUG2 endp


ODBCConnect proc pConnection:dword
 local theDiagState[50]:byte
 local theNativeState:dword
 local theMessageText[1024]:byte
 local iOutputNo:word

 mov edx,pConnection

 push edx
 invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE,addr (Connection ptr [edx]).hEnv
 pop edx
 .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
  push edx
  invoke SQLSetEnvAttr, (Connection ptr [edx]).hEnv,SQL_ATTR_ODBC_VERSION,SQL_OV_ODBC3,0
  pop edx
  .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
   push edx
   invoke SQLAllocHandle, SQL_HANDLE_DBC, (Connection ptr [edx]).hEnv, \
      addr (Connection ptr [edx]).hConn
   pop edx
   .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
    push edx
    invoke SQLDriverConnect, \
      (Connection ptr [edx]).hConn, NULL, \
      (Connection ptr [edx]).pInConnectString,\
      (Connection ptr [edx]).inConnectStringLength,\ ;输入的连接字符串及长度
      (Connection ptr [edx]).pOutConnStr,\
      (Connection ptr [edx]).outConnStrLength,\
      (Connection ptr [edx]).pOutConnStrLength,SQL_DRIVER_COMPLETE
    pop edx
    .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
     xor eax,eax
     ret
    .else

     push edx
     invoke SQLGetDiagRec,SQL_HANDLE_DBC,(Connection ptr [edx]).hConn,1,addr theDiagState,\
       addr theNativeState,addr theMessageText,1024,addr iOutputNo

     invoke MessageBox,NULL,addr theMessageText, addr theDiagState,MB_OK
     pop edx


     push edx
     invoke SQLFreeHandle, SQL_HANDLE_DBC, (Connection ptr [edx]).hConn
     pop edx
     invoke SQLFreeHandle, SQL_HANDLE_ENV, (Connection ptr [edx]).hEnv
     mov eax,4
     jmp err
    .endif
   .else
    invoke SQLFreeHandle, SQL_HANDLE_ENV, (Connection ptr [edx]).hEnv
    mov eax,3
    jmp err
   .endif
  .else
   invoke SQLFreeHandle, SQL_HANDLE_ENV, (Connection ptr [edx]).hEnv
   mov eax,2
   jmp err
  .endif
 .else
  jmp err
 .endif

err:
 ret
ODBCConnect endp

ODBCDisconnect proc pConnection:DWORD
 mov edx,pConnection
 push edx
 invoke SQLDisconnect, (Connection ptr [edx]).hConn
 pop edx
 push edx
 invoke SQLFreeHandle, SQL_HANDLE_DBC, (Connection ptr [edx]).hConn
 pop edx
 invoke SQLFreeHandle, SQL_HANDLE_ENV, (Connection ptr [edx]).hEnv

 xor eax,eax
 ret
ODBCDisconnect endp


;;reserved for some crash error
CloseProcQuery proc xhStmt:dword

 invoke SQLCloseCursor,xhStmt
 invoke SQLFreeHandle, SQL_HANDLE_STMT, xhStmt

CloseProcQuery endp


MakeInParam proc pParams:dword,paramIndex:dword,pBuffer:dword,bufferMax:dword,paramType:dword,paramDType:dword,paramDSize:dword,paramDeimalSize:dword

 mov edx,pParams
 xor ebx,ebx
 .while ebx < paramIndex
  add edx,sizeof Parameter
  inc ebx
 .endw

 m2m ( Parameter ptr [edx]).pParamValue,pBuffer
 m2m ( Parameter ptr [edx]).paramValueSize,bufferMax
 m2m ( Parameter ptr [edx]).paramType,paramType
 m2m ( Parameter ptr [edx]).paramDirection,SQL_PARAM_INPUT
 m2m ( Parameter ptr [edx]).paramDType,paramDType
 m2m ( Parameter ptr [edx]).paramDSize,paramDSize
 m2m ( Parameter ptr [edx]).paramDeimalSize,paramDeimalSize

 lea ecx, (Parameter ptr [edx]).paramStrL
 mov ( Parameter ptr [edx]).pParamStrL,ecx

 .if paramType == SQL_C_CHAR
  push edx
  invoke lstrlen,pBuffer
  pop edx
  mov (Parameter ptr [edx]).paramStrL,eax
 .elseif paramType == SQL_C_LONG
  mov (Parameter ptr [edx]).paramStrL,4
 .endif ;//

 xor eax,eax
 ret
MakeInParam endp


MakeOutParam proc pParams:dword,paramIndex:dword,pBuffer:dword,bufferMax:dword,paramType:dword,paramDType:dword,paramDSize:dword,paramDeimalSize:dword

 mov edx,pParams
 xor ebx,ebx
 .while ebx < paramIndex
  add edx,sizeof Parameter
  inc ebx

 .endw


 m2m ( Parameter ptr [edx]).pParamValue,pBuffer
 m2m ( Parameter ptr [edx]).paramValueSize,bufferMax
 m2m ( Parameter ptr [edx]).paramType,paramType
 m2m ( Parameter ptr [edx]).paramDirection,SQL_PARAM_INPUT_OUTPUT
 m2m ( Parameter ptr [edx]).paramDType,paramDType
 m2m ( Parameter ptr [edx]).paramDSize,paramDSize
 m2m ( Parameter ptr [edx]).paramDeimalSize,paramDeimalSize

 lea ecx, (Parameter ptr [edx]).paramStrL
 mov ( Parameter ptr [edx]).pParamStrL,ecx

 .if paramType == SQL_C_CHAR
  push edx
  invoke lstrlen,pBuffer
  pop edx
  mov (Parameter ptr [edx]).paramStrL,eax
 .elseif paramType == SQL_C_LONG
  mov (Parameter ptr [edx]).paramStrL,4
 .endif ;//

 xor eax,eax
 ret
MakeOutParam endp


MakeReturnParam proc pParams:dword,paramIndex:dword,pBuffer:dword

 mov edx,pParams
 xor ebx,ebx
 .if ebx < paramIndex
  add edx,sizeof Parameter
  inc ebx
 .endif

 m2m ( Parameter ptr [edx]).pParamValue,pBuffer
 m2m ( Parameter ptr [edx]).paramValueSize,4
 m2m ( Parameter ptr [edx]).paramType,SQL_C_LONG
 m2m ( Parameter ptr [edx]).paramDirection,SQL_PARAM_OUTPUT
 m2m ( Parameter ptr [edx]).paramDType,SQL_INTEGER
 m2m ( Parameter ptr [edx]).paramDSize,4
 m2m ( Parameter ptr [edx]).paramDeimalSize,0
 lea eax,( Parameter ptr [edx]).paramStrL
 m2m ( Parameter ptr [edx]).pParamStrL,eax
 m2m ( Parameter ptr [edx]).paramStrL,4

 ret
MakeReturnParam endp

;;
;;
;;;ProcName:{call proc(?, ?, ?)}
;;
RunProcQuery proc hConn:DWORD,phStmt:dword,pProcName:dword,pParams:dword,paramCount:dword
 local thStmt:dword
 local theDiagState[50]:byte
 local theNativeState:dword
 local theMessageText[1024]:byte
 local iOutputNo:word

 ;;分配语句句柄
 invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr thStmt;hStmt:SIMILAR commad object

 .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
  mov ecx,phStmt
  mov eax,thStmt
  mov [ecx],eax

  ;;建立参数列表
  mov edx,pParams
  mov ebx,1
  .while ebx <= paramCount
   push ebx
   push edx

   invoke SQLBindParameter,thStmt, ebx, \
   (Parameter ptr [edx]).paramDirection,\
   (Parameter ptr [edx]).paramType,\
   (Parameter ptr [edx]).paramDType,\
   (Parameter ptr [edx]).paramDSize,\
   (Parameter ptr [edx]).paramDeimalSize,\
   (Parameter ptr [edx]).pParamValue,\
   (Parameter ptr [edx]).paramValueSize,\
   (Parameter ptr [edx]).pParamStrL

   pop edx
   pop ebx

   add edx,sizeof Parameter
   inc ebx
  .endw

  ;;;;;多次重复的查询可以用这个
  ;invoke SQLPrepare, hStmt, addr Conn, sizeof Conn
  ;invoke SQLExecute, hStmt

  ;;;;;直接执行
  invoke SQLExecDirect, thStmt, pProcName,SQL_NTS;SIMILAR command.execute(sql)
  .if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO

   xor eax,eax
   ret
  .else

   mov eax,2
   jmp error
  .endif

 .else
  mov eax,1
  jmp error
 .endif

error:
 push eax
 invoke SQLGetDiagRec,SQL_HANDLE_STMT,thStmt,1,addr theDiagState,\
   addr theNativeState,addr theMessageText,1024,addr iOutputNo

 invoke MessageBox,NULL,addr theMessageText, addr theDiagState,MB_OK
 pop eax
 ret
RunProcQuery endp



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/cloudandy/archive/2008/11/14/3298046.aspx

Link: http://www.asm32.net/article_details.aspx?id=4589


浏览次数 42 发布时间 2009-09-26 14:43:03 从属分类 Win32汇编编程 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | Python | 书签 | ASP.Net书签 | 京ICP备09029108号-1