WIN32彙編實現基於API的ODBC編程

小站開通了:http://noteba.com/  

 

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章