Reparti em camadas
1 - Selec, insert, updade, delete, etc,..
2 - Verifica se esta conectado com banco de dados
3 - Faz a conexão, se não estiver
4 - Salvar conexão, na primeira conexao
5 - CLOSE - fecha Record set, sem fechar conexão
ADO_OPEN - É chamado quando você faz USE ('tabela'), select, update, etc...
ADO_Connection - Faz a conexão com banco de dados
ADO_GetConnection - Retorna conexão salva caso ja exista
ADO_SetConnection - Salva conexao, se não foi salva ainda
ADO_CLOSE - Fecha RecordSet, sem fechar conexão
Como retirei parte das mudanças que fiz em ADORDD, provavelmente vai da alguns erros de função, retirei o que vi, se der passe, que vejo se é necessária a função ou é só desativar chamada
Aceita um ou mais comando em um mesma string, select,Insert,update,etc,..
EX:
string := "insert into produto (codigo,descricao,valor) value ('001', 'arroz', 23.99);SELECT LAST_INSERT_ID;" //vai retorna um RecordSet com 1 registro e 1 campo last_insert_id
string := "insert into produto (codigo,descricao,valor) value ('001', 'arroz', 23.99)"
string := "SELECT LAST_INSERT_ID;"
*** SENARIO EM QUE ESTEJA COM MAIS DE UMA ESTAÇÃO DE TRABALHO ACESSANDO O MESMO BANCO DE DADOS/TABELA ***
SELECT LAST_INSERT_ID; // RETORNA ULTIMO ID, Quando tabela tem um campo auto_increment
SELECT MAX(ID) FROM produto //faz sentido quando só tem 1 pessoa que utiliza o banco de dados, senão pode vir o id de outra estação de trabalho que fez um insert antes de você executar o comando "select max"
No caso de um INSERT, seguido de um SELECT LAST_INSERT_ID, mesmo se outra estação de trabalho, fazer um INSERT, como você esta na mesma conexão, o resultado será o ID do seu INSERT, se você faz um INSERT, fecha conexão, e faz um SELECT LAST_INSERT_ID, corre o risco de pegar o ID de outro INSERT.
Código: Selecionar todos
STATIC FUNCTION ADO_OPEN( nWA, aOpenInfo )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL aField, nResult
LOCAL oRecordSet, nTotalFields, n, uRet
LOCAL aQuery, xx, nPos
IF Empty( aWAData[ WA_CONNECTION ] ) .and. !Empty(aOpenInfo[ UR_OI_CONNECT ])
aWAData[ WA_CONNECTION ] := win_oleAuto()
aWAData[ WA_CONNECTION ]:__hObj := aOpenInfo[ UR_OI_CONNECT ] /* "ADODB.Connection" */
ENDIF
ADO_AreaInfo( nWa )
IF !ADO_Connection( nWA, aOpenInfo )
RETURN HB_FAILURE
ENDIF
select( nWa )
IF Empty( aWAData[ WA_QUERY ] ) .and. (Empty(aWAData[ WA_TABLENAME ]) .or. Upper(aWAData[ WA_TABLENAME ]) = 'NULL')
RETURN HB_SUCCESS
ENDIF
IF Empty( aWAData[ WA_QUERY ] ) .or. aWAData[ WA_QUERY ] == "SELECT * FROM"
aWAData[ WA_QUERY ] := "SELECT * FROM " + aWAData[ WA_TABLENAME ]
ENDIF
aWAData[ WA_QUERY ] := StrTran(aWAData[ WA_QUERY ], hb_eol(), ' ')
aQuery := Split(aWAData[ WA_QUERY ], ';')
FOR xx := 1 TO Len(aQuery)
IF Empty(aQuery[xx])
LOOP
ENDIF
uRet := {'SELECT ', 'UPDATE ', 'DELETE ', 'INSERT ', 'CREATE ', 'DROP ', 'TRUNCATE ', 'USE ', 'SHOW ', 'VIEW ', 'DESCRIBE ',;
'REPLACE ', 'LOAD ', 'ALTER ', 'HANDLER ', 'RENAME ', 'USE ', 'START ', 'COMMIT ', 'ROLLBACK', 'SAVEPOINT ', 'LOCK ', 'UNLOCK '}
t_cQuery := Upper(Left(LTrim(aQuery[xx]), 20))
nPos := hb_At(' ', t_cQuery)
IF nPos > 0 .and. AScan(uRet, {|p| Left(t_cQuery, nPos) == p }) = 0 // prever ";" dentro de string
aQuery[xx] := aQuery[xx] + ';' + aQuery[xx + 1]
aQuery[xx + 1] := NIL
ENDIF
NEXT
t_cQuery := ''
FOR xx := Len(aQuery) TO 1 STEP -1
IF Empty(aQuery[xx])
aDelSize(aQuery, xx)
ENDIF
NEXT
BEGIN SEQUENCE WITH {|e| Break(e) }
FOR xx := 1 TO Len(aQuery)
uRet := AllTrim(aQuery[xx]) + ';'
//ADO_AddLog(uRet)
IF Upper(Left(uRet, 7)) == 'SELECT '
oRecordSet := win_oleCreateObject( "ADODB.Recordset" )
IF oRecordSet == NIL
//t_oUltError := BoniErrorNew(hb_langErrMsg( EG_OPEN ) + " (" + hb_langErrMsg( EG_UNSUPPORTED ) + ")", ;
///*Args*/, .T./*Candefault*/, .F./*CanRetry*/, .F./*CanSubstitute*/, /*Cargo*/, ;
//aOpenInfo[ UR_OI_NAME ]/*FileName*/, 0/*GenCode*/, ''/*Operation*/, 0/*Oscode*/, ;
//0/*Severity*/, 1001/*SubCode*/, ''/*SubSystem*/, 1/*Tries*/)
t_oUltError := ErrorNew()
UR_SUPER_ERROR( nWA, t_oUltError )
Break(t_oUltError)
ENDIF
//oRecordSet:CursorLocation = adUseServer
oRecordSet:CursorLocation := adUseClient
IF Lower( Right( aOpenInfo[ UR_OI_NAME ], 4 ) ) == ".dbf"
oRecordSet:CursorType := adOpenStatic
oRecordSet:LockType := adLockPessimistic
ELSE
oRecordSet:CursorType := adOpenDynamic
oRecordSet:LockType := adLockOptimistic
//oRecordSet:CommandTimeOut := 600 // seconds
//oRecordSet:ConnectionTimeOut := 600 // seconds
ENDIF
IF Upper( aWAData[ WA_ENGINE ] ) == 'DBF' .or. Upper( aWAData[ WA_ENGINE ] ) == 'DBFOLEDB' ;
.or. Upper( aWAData[ WA_ENGINE ] ) == 'VFPOLEDB' ;
.or. Upper( aWAData[ WA_ENGINE ] ) == 'SQLITE' .or. Upper( aWAData[ WA_ENGINE ] ) == 'ADS'
oRecordSet:CommandTimeOut := 20
ENDIF
//qt aguarda 'Conectando ao DB ' + t_cServer to oAtencao
oRecordSet:CacheSize = 30
t_Time := Seconds()
oRecordSet:Open( uRet, aWAData[ WA_CONNECTION ] )
t_Time := Seconds() - t_time
//oAtencao:close()
//ADO_AddLog()
aWAData[ WA_CATALOG ] := win_oleCreateObject( "ADOX.Catalog" )
aWAData[ WA_CATALOG ]:ActiveConnection := aWAData[ WA_CONNECTION ]
IF Empty( aWAData[ WA_CATALOG ] )
aWAData[ WA_CATALOG ] := aWAData[ WA_CONNECTION ]:OpenSchema( adSchemaIndexes )
ENDIF
IF Empty( aWAData[ WA_CATALOG ] )
//t_oUltError := BoniErrorNew(hb_langErrMsg( EG_OPEN ) + " (" + hb_langErrMsg( EG_UNSUPPORTED ) + ")", ;
///*Args*/, .T./*Candefault*/, .F./*CanRetry*/, .F./*CanSubstitute*/, /*Cargo*/, ;
//aOpenInfo[ UR_OI_NAME ]/*FileName*/, 0/*GenCode*/, ''/*Operation*/, 0/*Oscode*/, ;
//0/*Severity*/, 1001/*SubCode*/, ''/*SubSystem*/, 1/*Tries*/)
t_oUltError := ErrorNew()
UR_SUPER_ERROR( nWA, t_oUltError )
Break(t_oUltError)
ENDIF
aWAData[ WA_RECORDSET ] := oRecordSet
aWAData[ WA_BOF ] := aWAData[ WA_EOF ] := .F.
UR_SUPER_SETFIELDEXTENT( nWA, nTotalFields := oRecordSet:Fields:Count )
FOR n := 1 TO nTotalFields
aField := Array( UR_FI_SIZE )
aField[ UR_FI_NAME ] := oRecordSet:Fields( n - 1 ):Name
aField[ UR_FI_TYPE ] := ADO_GETFIELDTYPE( oRecordSet:Fields( n - 1 ):Type )
aField[ UR_FI_TYPEEXT ] := 0
IF aField[ UR_FI_TYPE ] = adLongVarChar
aField[ UR_FI_LEN ] := 10
ELSE
aField[ UR_FI_LEN ] := ADO_GETFIELDSIZE( aField[ UR_FI_TYPE ], oRecordSet:Fields( n - 1 ):DefinedSize )
ENDIF
aField[ UR_FI_DEC ] := 0
#ifdef UR_FI_FLAGS
aField[ UR_FI_FLAGS ] := 0
#endif
#ifdef UR_FI_STEP
aField[ UR_FI_STEP ] := 0
#endif
UR_SUPER_ADDFIELD( nWA, aField )
NEXT
nResult := HB_SUCCESS
IF nTotalFields > 0
nResult := UR_SUPER_OPEN( nWA, aOpenInfo )
IF nResult == HB_SUCCESS
ADO_GOTOP( nWA )
ENDIF
ELSE
ADO_CLOSE( nWa )
ENDIF
ELSE
t_Time := Seconds()
aWAData[ WA_CONNECTION ]:Execute( uRet )
t_Time := Seconds() - t_Time
//ADO_AddLog()
ENDIF
NEXT
RECOVER USING t_oUltError
nResult := HB_FAILURE
ADO_CLOSE( nWa )
UR_SUPER_ERROR( nWA, t_oUltError )
//ADO_AddLog()
END BEGIN
Select(nWa)
RETURN nResult
STATIC FUNCTION ADO_Connection( nWA ) //, aOpenInfo )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL lResult
LOCAL uRet, oSplashScreen
BEGIN SEQUENCE WITH {|e| Break(e) }
/*
qt aguarda 'AGUARDE;Conectando;Servidor de dados [' + t_cserver + ']' to oSplashScreen button ok .T. button Cancela .T. message Hide()
oSplashScreen:Ok:SetEnabled(.F.)
oSplashScreen:Cancela:SetEnabled(.F.)
QAppGet():ProcessEvents()
*/
aWAData[ WA_TABLENAME ] := t_cTableName
aWAData[ WA_QUERY ] := t_cQuery
aWAData[ WA_USERNAME ] := t_cUserName
aWAData[ WA_PASSWORD ] := t_cPassword
aWAData[ WA_SERVER ] := t_cServer
aWAData[ WA_ENGINE ] := t_cEngine
IF Empty( aWAData[ WA_CONNECTION ] )
aWAData[ WA_CONNECTION ] := ADO_GetConnection()
ENDIF
// prever perda de connecção anteriormente conectado
IF !Empty( aWAData[ WA_CONNECTION ] ).and. aWAData[ WA_CONNECTION ]:State != adStateOpen
IF aWAData[ WA_CONNECTION ]:State = adStateClosed
aWAData[ WA_CONNECTION ] := NIL
ELSE
oSplashScreen:Cancela:SetEnabled(.T.)
oSplashScreen:Mensagem:SetText('AGUARDE;Conexao em andamento;Servidor de dados [' + t_cserver + ']')
QAppGet():ProcessEvents()
uRet := 0
WHILE aWAData[ WA_CONNECTION ]:State != adStateClosed .and. aWAData[ WA_CONNECTION ]:State != adStateOpen .and. !oSplashScreen:Cancelado
PausaSleep(1000)
uRet ++
IF uRet > 9
EXIT
ENDIF
ENDDO
//oSplashScreen:Cancela:SetEnabled(.F.)
QAppGet():ProcessEvents()
IF aWAData[ WA_CONNECTION ]:State != adStateClosed .and. aWAData[ WA_CONNECTION ]:State != adStateOpen
aWAData[ WA_CONNECTION ]:Cancel()
ENDIF
IF aWAData[ WA_CONNECTION ]:State != adStateClosed
aWAData[ WA_CONNECTION ]:Close()
ENDIF
IF aWAData[ WA_CONNECTION ]:State != adStateOpen
aWAData[ WA_CONNECTION ] := NIL
ENDIF
ENDIF
ENDIF
IF Empty( aWAData[ WA_CONNECTION ] )
//oSplashScreen:Mensagem:SetText('AGUARDE;Conectando;Servidor de dados [' + t_cserver + ']')
//QAppGet():ProcessEvents()
//ADO_AreaInfo( nWa )
aWAData[ WA_CONNECTION ] := win_oleCreateObject( "ADODB.Connection" )
IF Empty(t_cCS)
t_cCS := NIL
ENDIF
//t_cCS := ConnectionString(aWAData[ WA_ENGINE ], 'Open', aWAData[ WA_SERVER ], iif(Empty(t_cDataBase), t_cAlias, t_cDataBase), aWAData[ WA_USERNAME ], aWAData[ WA_PASSWORD ], t_cPorta, aWAData[ WA_TABLENAME ], t_cCS )
//ex: MYSQL, MariaDB
//t_cCs := "Provider={_PROVIDER_};Driver={MariaDB ODBC 3.1 Driver};Server={_SERVER_};Port={_PORT_};Database={_DATABASE_};uid={_USER_};pwd={_PASSWORD_};Collation=latin1_swedish_ci;AUTO_RECONNECT=1;Option=3;STMT;"
t_cCs := "Provider={_PROVIDER_};Driver={MySQL ODBC 5.1;Server={_SERVER_};Port={_PORT_};Database={_DATABASE_};uid={_USER_};pwd={_PASSWORD_};Option=3;STMT;"
//ADO_AddLog(t_cCS)
t_Time := Seconds()
aWAData[ WA_CONNECTION ]:Open( t_cCS )
ENDIF
aWAData[ WA_CONNOPEN ] := .T.
lResult := .T.
RECOVER USING t_oUltError
aWAData[ WA_CONNECTION ] := NIL
aWAData[ WA_CONNOPEN ] := .F.
lResult := .F.
END BEGIN
ADO_SetConnection(aWAData[ WA_CONNECTION ])
t_Time := Seconds() - t_time
oSplashScreen:Close()
QAppGet():ProcessEvents()
//ADO_AddLog()
IF lResult
ADO_AreaInfoSet(nWA)
ENDIF
RETURN lResult
STATIC FUNCTION ADO_GetConnection(cServer, cPorta, cDataBase, cUser, cPassWord)
LOCAL cChave, uRet
DEFAULT cServer TO t_cServer
DEFAULT cPorta TO t_cPorta
DEFAULT cDataBase TO t_cDataBase
DEFAULT cUser TO t_cUserName
DEFAULT cPassWord TO t_cPassWord
cChave := Lower(cServer + '-' + cPorta + '-' + cDataBase) + '-' + cUser + '-' + cPassWord
IF hb_hPos(t_hConnection, cChave) > 0
uRet := t_hConnection[cChave]
ENDIF
RETURN uRet
STATIC FUNCTION ADO_SetConnection(oConn, cServer, cPorta, cDataBase, cUser, cPassWord)
LOCAL nPos, cChave, uRet
DEFAULT cServer TO t_cServer
DEFAULT cPorta TO t_cPorta
DEFAULT cDataBase TO t_cDataBase
DEFAULT cUser TO t_cUserName
DEFAULT cPassWord TO t_cPassWord
cChave := Lower(cServer + '-' + cPorta + '-' + cDataBase) + '-' + cUser + '-' + cPassWord
nPos := hb_HPos(t_hConnection, cChave)
IF nPos = 0
IF oConn <> NIL
t_hConnection[cChave] := oConn
uRet := oConn
ENDIF
ELSE
uRet := t_hConnection[cChave]
IF oConn = NIL
hb_HDel(t_hConnection, cChave)
ENDIF
ENDIF
RETURN uRet
STATIC FUNCTION ADO_CLOSE( nWA )
LOCAL aWAData := USRRDD_AREADATA( nWA )
LOCAL oRecordSet := USRRDD_AREADATA( nWA )[ WA_RECORDSET ]
BEGIN SEQUENCE WITH {|e| Break(e) }
IF !Empty(oRecordSet)
oRecordSet:Close()
ENDIF
RECOVER USING t_oUltError
// faz nada
END SEQUENCE
BEGIN SEQUENCE WITH {|e| Break(e) }
IF !Empty( aWAData[ WA_CONNOPEN ] ) .AND. !Empty( aWAData[ WA_CONNECTION ] )
IF aWAData[ WA_CONNECTION ]:State != adStateClosed
IF aWAData[ WA_CONNECTION ]:State != adStateOpen
aWAData[ WA_CONNECTION ]:Cancel()
ENDIF
ENDIF
ENDIF
RECOVER USING t_oUltError
// faz nada
END SEQUENCE
RETURN UR_SUPER_CLOSE( nWA )