Oracle - gravar dados

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Boa tarde colegas. (Alexandre)

Banco do Oracle conectado. Leio os valores arquivados no Banco Oracle.

Agora preciso gravar dados e estou apanhado novamente. Quase como "cachorro magro...."

tenho a seguinte string

Código: Selecionar todos

*      cSql := "update PRESCR_LAB_INTEGRACAO_V set DT_INTEGRACAO = sysdate " +;
*              "where NR_PRESCRICAO = 1448492"
O objeto é "oRs"

Como deve ser a sintaxe para gravar os dados do cSql na Banco ?

Já tentei:

Código: Selecionar todos

:source := "update PRESCR_LAB_INTEGRACAO_V set DT_INTEGRACAO = c_Dat where NR_PRESCRICAO = 1448492"
ou
oRs:source := "update PRESCR_LAB_INTEGRACAO_V set DT_INTEGRACAO = c_Dat where NR_PRESCRICAO = 1448492"
Nenhuma funcionou....

Tudo via ADO.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Oracle - gravar dados

Mensagem por alxsts »

Olá!

Usando ADO ficaria mais ou menos assim:

Código: Selecionar todos

#include "ado.ch"
#include "set.ch"
#include "hbcompat.ch"
#include "Oracle.ch"
#include "sqlora.ch"
**
PROCEDURE Main()

   Set( _SET_DATEFORMAT, "dd/mm/yyyy" )

   UpdateRow( 1448492 )

RETURN

//------------------------------------------------------------------------------------------

PROCEDURE UpdateRow( nPrescricao )

   LOCAL oConect, oRs, oErr, aRs, cSql

   *
   Try

      oConect := TOLEAUTO():New("ADODB.Connection")

      //  Ajustar conexão Oracle
      cCn := "Provider=OraOLEDB.Oracle;"           +;
             "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.0.250)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=dbprod)));" +;
             "User ID=LABORATORIO;"                +;
             "Password=sistema;"                 +;
             "FetchSize=100;"                      +;
             "CacheType=Memory;"                   +;
             "PLSQLRSet=True;"
      *

      oRs := TOLEAUTO():New("ADODB.RecordSet")

      cSql := "SELECT DT_INTEGRACAO" + ;
              "  FROM PRESCR_LAB_INTEGRACAO_V" + ;
              " WHERE NR_PRESCRICAO = " + LTrim( STR( nPrescricao ) ) 

      With Object oRs
         *
         :cursorType := adOpenKeyset 
         :lockType := adLockOptimistic
         :activeConnection( oConect )
         :cursorLocation = adUseServer
         :maxRecords = 100000
         :cacheSize = 100
         :source := cSql

         :open()


         If ! :Eof()
            :fields( "DT_INTEGRACAO" ) := Transform( DtoS( Date() ), "@9999-99-99" + " " + Time() ) // em Harbour pode usar DateTime() formatado corretamente
            :update()
         Else
            ? "RS vazio"
         Endif
         
         *
      End With
      *

      Catch oErr
         Alert( "Error: " + oErr:Operation + " -> " + oErr:Description )
      
      Finnaly

         oRS:close()
         oConect:Close()

         oRS := NIL
         oConect := NIL
   End

   *

 RETURN
//--------------------------------------------------------------------------------------------
Não compilei esse código. Provavelmente tem erros.

Esse método, a meu ver, não é o ideal. Escrever seus comandos SQL dentro dos teus fontes, com o passar do tempo, gera um trabalho monstruoso de manutenção. Por exemplo, se você alterar o layout de uma tabela, terá que atualizar a maioria dos programas onde tem SQL escrito envolvendo a tabela alterada.

Procure colocar todas as tuas operações de banco (CRUD) e lógica de negócios em stored procedures (que ficarão armazenadas no próprio banco de dados, como o nome já diz) e executá-las pelo ADO, como visto no exemplo postado pelo Alexandre Simões em outro tópico.

Alem disso, essa prática permite que você configure o teu sistema para utilizar qualquer banco de dados, mudando apenas a connection string. Por exemplo: você cria diversos bancos de dados para o teu sistema (Oracle, SQL Server, MySQL, Postgre, Firebird). Em cada um dos bancos, existirão as tabelas, procedures e outros objetos, todos escritos na sintaxe nativa de cada banco. Dessa forma, se o cliente escolher um determinado banco de dados, é só adaptar a connection string.
[]´s
Alexandre Santos (AlxSts)
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Boa tarde Alexandre.

Testamos o teu código e obtivemos êxito. Veja o código testado.

Código: Selecionar todos

      cDatRet := "select D.DT_INTEGRACAO INTEGRACAO from PRESCR_LAB_INTEGRACAO_V D where D.NR_PRESCRICAO = 1450163"

      WITH Object oDatRet
         *
         :cursorType := adOpenForwardOnly                //adOpenForward //adOpenDynamic adOpenStatic //
         :activeConnection( oConect )
         :cursorLocation = adUseServer
         :maxRecords = 100000
         :cacheSize = 100
         :source := cDatRet
         *
         :open()
         *

clear
? "Tabela aberta"
? :Fields( "DT_INTEGRACAO" ).value

            :fields( "DT_INTEGRACAO" ) := "28/11/2013"
            :update()
Na linha :fields( "DT_INTEGRACAO" ) := "28/11/2013" temos um erro, conforme o JPG do anexo.

Passamos a tarde toda tentando de todas as formas.
Observe que até abrimos um segundo objeto "oDatRet", que também não resolveu. Observe que o valor que está na tabela é impressa na tela mas não permite a alteração/gravaçãp. Tentamos com o campo vazio como também com campo contendo um valor data.
Anexos
Erro Oracle.jpg
Erro Oracle.jpg (9.48 KiB) Exibido 3644 vezes
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Oracle - gravar dados

Mensagem por alxsts »

Olá!

Parece que o nome de campo que você tem na coleção de campos do record set não existe na tabela do banco. Verifique.

O formato padrão de data no Oracle é diferente do formato no xBase, assim como outros tipos de dados. Você terá que tratar isso.

Altere a linha

Código: Selecionar todos

:fields( "DT_INTEGRACAO" ) := "28/11/2013"
para

Código: Selecionar todos

:fields( "DT_INTEGRACAO" ) := Transform( DtoS( Date() ), "@R9999-99-99")
Verifique se encontra algo sobre o erro no Google.
[]´s
Alexandre Santos (AlxSts)
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Boa noite Alexandre.

Passamos o dia de hoje procurando algum erro. Veja o prg que estamos usando:

Código: Selecionar todos

**
#include "ado.ch"
#include "set.ch"
*#include "hbcompat.ch"
#include "Oracle.ch"
#include "sqlora.ch"
#include "adoXb.ch"
**
PROCEDURE Main()
   *
   LOCAL oConect, oRs, aRs, cSql, oDatRet
   *
   clear
   *
   Try
      *
      Set( _SET_DATEFORMAT, "dd/mm/yyyy" )
      *
      oConect := TOLEAUTO():New("ADODB.Connection")
      *
      //  Oracle XE
      cCn := "Provider=MSDAORA.1;Password=aloisklab;User ID=LABORATORIO;Data Source=dbprod;Persist Security Info=True;"
      *
      ? "Conect String:>"
      ? cCn + "<<=="
      ? "=================================="
      *
      oConect:Open( cCn )
      *
      oRs     := TOLEAUTO():New("ADODB.RecordSet")
      *
      cDatRet := "select DS_INTEGRACAO from PRESCR_LAB_INTEGRACAO_V where NR_PRESCRICAO = 1450163"
      *
      With Object oRs
         *
         :cursorType       := adOpenKeyset 
         :lockType         := adLockOptimistic
         :activeConnection( oConect )
         :cursorLocation   := adUseServer
         :maxRecords       := 100000
         :cacheSize        := 100
         :source           := cDatRet
         *
         :open()
         *
         If ! :Eof()
            *
            ? "antes de ler."
            ? :fields( "DS_INTEGRACAO" ):value
            *
            ? "antes do ':fields' para preparar para a gravação"
            :fields( "DS_INTEGRACAO" ) := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            *
            ? "antes do update"
            *
            :update()
            *
         Else
            Alert( "Registro do Banco Oracle não foi encontrado;;Verifique;;Gravação dos dados CANCELADA." )
         Endif
         *
      END WITH
      *
   Catch oErr
      *
      Alert( "Error: ->" + oErr:Operation + ";;Descri‡Æo: ->" + oErr:Description )
      *
   Finally
      *
      oRS:close()
      oConect:Close()
      RELEASE oRS, oConect
      *
   End
   *
 RETURN
//--------------------------------------------------------------------------------
Nas linhas 48 e 49 fizemos a leitura que está gravada na Tabela. Isto quer dizer que a Tabela está disponível para a Leitura.
O Campo tem gravado o valor "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy".

Para testar, nas linhas 51 e 52 temos linha ':Fields', onde tentamos preparar o Campo para ter o seu conteúdo ser substituído e gravado com o valor "xxxxxxxxxxxxxxxxxxxxxx", mas aqui ocorre o erro mencionado em minha mensagem anterior. Não chega na linha 54.

Se o Banco está disponível, está aberto, e sendo lido, então tem algo de errado na 52.

O nome do Campo está correto pois o valor foi lido, mas nele não conseguimos gravar outro valor.

Pesquisamos via Google e não obtivemos uma resposta que nos ajudasse.

Pensando que a dificuldade pudesse ser a data que na realidade precisamos gravar decidimos usar um outro Campo que fosse Caracter para testes, mas que também não não nos permitiu dar qualquer passo adiante.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1299
Registrado em: 06 Jul 2004 00:44
Contato:

Oracle - gravar dados

Mensagem por ANDRIL »

Não utilizo nada do que voce esta utilizando, mais vou dar um palpite.

Troque esta linha
:fields( "DS_INTEGRACAO" ) := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Por esta
:fields( "DS_INTEGRACAO" ) :value := "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Como disse, é apenas um palpite.
Boa sorte.
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Bom dia Colega Andril.

Já testamos esta opção também e também deu erro de sintaxe.

Outro detalhe: Aquele erro citado na mensagem do dia 28 (acima) ocorre na linha 2047 no arquivo Win32Ole.prg da pasta SOURCE/RTL do xHarbour. Agora não sei explicar como e porque ocorre este erro.

Nós já estamos "atirando até em formiga e mosquito". Opiniões e palpites serão bem-vindos.

Já estamos pensando em usar uma Stored Procedure para gravar somente um dado, que será no formato Data/hora/minuto/segundo. Assim que os dados necessários forem lidos, deverá ser gravada a data como prova de que aquela ficha foi lida. Se pudéssemos usar leitura de dados seguidos da gravação em um só procedimento o processo se tornaria fácil e mais rápido.

Também já testamos usar a sintaxe do ADO mas parece que está faltando algo. Os arquivos "AdoXb.ch" e "AdoXb.prg" já estão incorporados. Não sei se é uma LIB ou se é necessário instalar algum software específico do ADO.
Alguém saberia me orientar ?
Quais os arquivos que eu preciso para usar o ADO para todas as operações ?
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1299
Registrado em: 06 Jul 2004 00:44
Contato:

Oracle - gravar dados

Mensagem por ANDRIL »

Hasse, como disse não tenho conhecimento do que voce esta usando.
Pra ajudar o erro reportado não ajuda quase em nada. Parece-me algo relacionado a array.

Voce ja tentou ao invez de utilizar o método :update() do recordset, criar uma nova query com UPDATE e executá-la para ver se ocorre o mesmo erro. Sei que não faz muito "sentido" visto que o recordset é justamente para evitar isso, mais seria apenas para verificar outra possibilidade.

Voce conseguiu gravar outros dados no seu banco oracle, ou seja, fazer cadastro outros updates direto do seu sistema? Caso não, verifique as permissões de gravação no banco no seu provedor e também as permissões do usuário.

Até+
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Oracle - gravar dados

Mensagem por asimoes »

Estou usando sem problemas.
É só adaptar.

Código: Selecionar todos

#include "adordd.ch"

FUNCTION MAIN
PRIVATE lConexaoOk:=.T.
   ConexaoOracle(@lConexaoOk)
   TRY
      RegistroBanco(TABELA->(DbStruct()),"U") //U=UPDATE, I=INCLUDE
   CATCH oErr
      TONE(800,4)
      TONE(800,4)
      Pare(oErr:Operation + " ERRO DE CONEXÃO AO BANCO")
   END
RETURN Nil


FUNCTION ConexaoOracle(lConexaoOk)
LOCAL oErr
PUBLIC oConnection, oRecordSet, oCommand
   
   cApp               :="A_026"
   cBancoOracle       :='DS01'
   cEsquemaOracle     :=cApp
   cSenhaUsuarioOracle:=cApp
   cOwner             :='ENF'

   cConexao:="Provider=OraOLEDB.Oracle;Data Source="+Trim(cBancoOracle)+";User ID="+Trim(cEsquemaOracle)+";Password="+Trim(cSenhaUsuarioOracle)+";FetchSize=200;CacheType=Memory;PLSQLRSet=True;TNS=DS01;OWNER="+cOwner
   
   #ifdef HOMOLOG
      nPos               :=AScan( aConexao, { |reg| reg[1] == cApp } )
      cBancoOracle       :='H01'
      cEsquemaOracle     :=cApp
      cSenhaUsuarioOracle:=aConexao[nPos,2]
      cConexao:="Provider=OraOLEDB.Oracle;Data Source="+Trim(cBancoOracle)+";User ID="+Trim(cEsquemaOracle)+";Password="+Trim(cSenhaUsuarioOracle)+";FetchSize=200;CacheType=Memory;PLSQLRSet=True;TNS=H01;OWNER="+cOwner
   #endif   
   
   #ifdef PROD
      nPos               :=AScan( aConexao, { |reg| reg[1] == cApp } )
      cBancoOracle       :='P01'
      cEsquemaOracle     :=cApp
      cSenhaUsuarioOracle:=aConexao[nPos,2]
      cConexao:="Provider=OraOLEDB.Oracle;Data Source="+Trim(cBancoOracle)+";User ID="+Trim(cEsquemaOracle)+";Password="+Trim(cSenhaUsuarioOracle)+";FetchSize=200;CacheType=Memory;PLSQLRSet=True;TNS=P01;OWNER="+cOwner
   #endif
   
   DO WHILE .T.
      TRY
         oConnection:=Nil
         CriaObjetoConnection(@oConnection)                
         oConnection:Open(cConexao)
         IniciaRecordSet()
         lConexaoOk:=.T.
      CATCH oErr
         TONE(800,4)
         TONE(800,4)
         Pare(oErr:Operation + " ERRO DE CONEXÃO AO BANCO")
         lConexaoOk:=.F.
      END
      EXIT
   ENDDO
RETURN lConexaoOk

FUNCTION IniciaRecordSet
   oRecordSet:=Nil
   CriaObjetoRecordSet(@oRecordSet)
   oRecordSet:CursorType := adOpenDynamic
   oRecordSet:ActiveConnection:=oConnection          
   oCommand:=IniciaCommand()
RETURN Nil

FUNCTION QueryConsulta(cQuery)
LOCAL cOperacao:="", aConsulta:={}
      oConnection:Execute( cQuery )
      oRecordSet:Source:=cQuery
      oRecordSet:Open()
      IF !oRecordSet:Eof
         aConsulta:=oRecordSet:GetRows()
         oRecordSet:MoveFirst()
      ENDIF
      cOperacao:=IF(oRecordSet:Eof,"I","U")
RETURN cOperacao

FUNCTION CriaObjetoConnection(oObjeto)
LOCAL oObjetoConnection:=Win_OleCreateObject( "ADODB.connection" )
   IF oObjeto!=Nil
      oObjeto:=Nil
   ENDIF
   oObjeto:=oObjetoConnection
RETURN oObjetoConnection

FUNCTION CriaObjetoCommand(oObjeto)
LOCAL oObjetoCommand:=Win_OleCreateObject( "ADODB.Command" )
   IF oObjeto!=Nil
      oObjeto:=Nil
   ENDIF
   oObjeto:=oObjetoCommand
RETURN oObjetoCommand

FUNCTION CriaObjetoRecordSet(oObjeto)
LOCAL oObjetoRecordSet:=Win_OleCreateObject( "ADODB.recordset" )
   IF oObjeto!=Nil
      oObjeto:=Nil
   ENDIF
   oObjeto:=oObjetoRecordSet
RETURN oObjetoRecordSet

FUNCTION IniciaCommand
  oCommand:=Nil
  oCommand:=CriaObjetoCommand(@oCommand) 
  oCommand:ActiveConnection:=oConnection
  oCommand:CommandType:= adCmdText 
RETURN oCommand

FUNCTION Transforme(xVar)
LOCAL dData
   IF ValType(xVar) = 'C'
      xVar:="'"+xVar+"'"
   ENDIF
   IF ValType(xVar) = 'N'
      xVar:=AllTrim(Str(xVar))
   ENDIF
   IF ValType(xVar) = 'D'
      IF Empty(xVar)
         xVar:="NULL"   
      ELSE
         dData:=DTOC(xVar)
         xVar:="TO_DATE("+Transforme(dData)+","+"'DD/MM/YYYY')"   
      ENDIF
   ENDIF
   IF ValType(xVar) = 'L'
      xVar:=IF(xVar,'T','F')
   ENDIF   
RETURN xVar

FUNCTION RegistroBanco(aTheDBF,cOperacao)
LOCAL cResult:=""
      DO CASE
         CASE cOperacao = "U"
              cResult:=QueryConsulta("SELECT ROWID,INSCIPTU FROM ENF.BENF3106_FUSION WHERE INSCIPTU = "+Transforme(BENF3106->INSCIPTU)+ " ORDER BY INSCIPTU"  )
              IF cResult = "I"
                 RegistroBanco(aTheDBF,cResult)
                 RETURN Nil 
              ENDIF
              cRowID:=oRecordSet:Fields( 0 ):value
              oRecordSet:Close()
              cSet:=''
              FOR X:=2 TO Len(aTheDBF)
                 cNomeCampo:=Upper(aTheDBF[X,1])
                 cTheValue := &(aTheDBF[X,1] )
                 IF ValType(cTheValue) = 'D'
                    IF Empty(cTheValue)
                       cTheValue:="NULL"
                    ELSE
                       dData:=DTOC(cTheValue)
                       cTheValue:="TO_DATE("+Transforme(dData)+","+"'DD/MM/YYYY')"
                    ENDIF
                 ENDIF
                 IF ValType(cTheValue) = 'L'
                    cTheValue:=IF(cTheValue,'T','F')
                 ENDIF
                 cSet+=cNomeCampo+'='+Transforme(cTheValue)+IF(X < Len(aTheDBF),',','')
              NEXT
              cTheQuery:="UPDATE ENF.BENF3106_FUSION SET "+ cSet +" WHERE INSCIPTU = "+Transforme(nInscIPTU)
              oConnection:BeginTrans()
              oConnection:Execute( cTheQuery )
              oConnection:CommitTrans()
              HWG_DOEVENTS()
         CASE cOperacao = "I"
              cQueryLeft := "INSERT INTO ENF.BENF3106_FUSION ("
              nEspaco:=Len(cQueryLeft)
              FOR X:=1 TO Len(aTheDBF)
                 cNomeCampo:=Upper(aTheDBF[X,1])
                 IF AllTrim(cNomeCampo) == "DESC"
                    cNomeCampo:='"'+'DESC'+'"'
                 ENDIF
                 IF AllTrim(cNomeCampo) == "DATA"
                    cNomeCampo:='"'+'DATA'+'"'
                 ENDIF
                 cQueryLeft += IF(X > 1,Space(nEspaco),"")+PADR(cNomeCampo + IF(X < Len(aTheDBF),", ",""),12) + HB_EOL()
              NEXT
              cQueryLeft+=" ) VALUES ("
              nEspaco:=Len(cQueryLeft)-RAT( " ) VALUES (", cQueryLeft )+33
              cValorInsert:=""
              cTheQuery := cQueryLeft
              cValor:=""
              FOR X:=1 TO Len(aTheDBF)
                 cNomeCampo:=Upper(aTheDBF[X,1])
                 IF AllTrim(cNomeCampo) == "DESC"
                    cNomeCampo:='"'+DESCR+'"'
                 ENDIF
                 IF AllTrim(cNomeCampo) == "DATA"
                    cNomeCampo:='"'+'DATA'+'"'
                 ENDIF
                 cTheValue:=&(aTheDBF[X,1] )
                 IF aTheDBF[X,2] $ "NDCM"
                    IF Empty(cTheValue)
                       cTheValue:=Nil
                    ENDIF
                 ENDIF
                 DO CASE
                    CASE aTheDBF[X,2] = "C"
                         IF cTheValue <> NIL
                            cTheValue:=RTRIM(cTheValue)
                         ENDIF
                 ENDCASE
                 cEspaco:=IF(X > 1,Space(nEspaco),"")
                 DO CASE
                    CASE aTheDBF[X,2] = "N"
                         cTheQuery += "?" + IF(X < Len(aTheDBF),", ","")
                         Param0 := oCommand:CreateParameter(cNomeCampo, adNumeric, adParamInput,aTheDBF[X,3],cTheValue)
                         oCommand:Parameters:Append( Param0)
                    CASE aTheDBF[X,2] = "D"
                         cTheQuery += "?" + IF(X < Len(aTheDBF),", ","")
                         Param0 := oCommand:CreateParameter(cNomeCampo, adDate, adParamInput,aTheDBF[X,3],cTheValue)
                         oCommand:Parameters:Append( Param0)
                    CASE aTheDBF[X,2] = "L"
                         cTheQuery += "?"+ IF(X < Len(aTheDBF),", ","")
                         cTheValue:=IF(cTheValue,1,0)
                         Param0 := oCommand:CreateParameter(cNomeCampo, adNumeric, adParamInput,aTheDBF[X,3],cTheValue)
                         oCommand:Parameters:Append( Param0)
                    CASE aTheDBF[X,2] = "C"
                         cTheQuery += "?"+IF(X < Len(aTheDBF),", ","")
                         Param0 := oCommand:CreateParameter(cNomeCampo, adVarChar, adParamInput,aTheDBF[X,3],cTheValue)
                         oCommand:Parameters:Append( Param0)
                    CASE aTheDBF[X,2] = "M"
                         cTheQuery += "?"+IF(X < Len(aTheDBF),", ","")
                         Param0 := oCommand:CreateParameter(cNomeCampo, adLongVarChar, adParamInput,Len(IF(cTheValue=Nil,aTheDBF[X,1],cTheValue)),cTheValue)
                         oCommand:Parameters:Append( Param0)
                 ENDCASE
              NEXT
              cTheQuery+=" )"
              oRecordSet:Close()
              oConnection:BeginTrans()
              oCommand:CommandText:=cTheQuery
              oCommand:Execute()
              oCommand:=IniciaCommand()
              Param0:=Nil
              oConnection:CommitTrans()
              HWG_DOEVENTS()
      ENDCASE
RETURN Nil
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Bom dia colegas.

ANDRIL:
Voce ja tentou ao invez de utilizar o método :update() do recordset, criar uma nova query com UPDATE e executá-la para ver se ocorre o mesmo erro. Sei que não faz muito "sentido" visto que o recordset é justamente para evitar isso, mais seria apenas para verificar outra possibilidade.
Já tentamos esta solução mas não conseguimos.

Não me lembro mais exatamente como tínhamos montado a linha, mas acredito que era algo como:

Código: Selecionar todos

      cDatRet := "select DS_INTEGRACAO from PRESCR_LAB_INTEGRACAO_V where NR_PRESCRICAO = 1450163"
      With Object oRs
         :cursorType       := adOpenKeyset 
         :lockType         := adLockOptimistic
         :activeConnection( oConect )
         :cursorLocation   := adUseServer
         :maxRecords       := 100000
         :cacheSize        := 100
         :source           := cDatRet
         :open()
         :update DS_INTEGRACAO := "yyyyyyyyyyyyyyyyyyyyyy"
Você teria uma sugestão da linha de comando ?

Pensamos em fazer algo como a montagem de uma linha em uma variável semelhante àquela usada conexão ao banco, como:

Código: Selecionar todos

      cUpd := ":update from PRESCR_LAB_INTEGRACAO_V where NR_PRESCRICAO = 1450163" DS_INTEGRACAO := "yyyyyyyyyyyyyyyyyyyyyy"
      oCommand:CommandText:=cUpd
      oCommand:Execute()
Mas também falhou. Se o colega pudesse nos orientar como se faz isto....

ASIMOES:
Agradecemos a tua generosa atenção, disponibilizando o Código, mas ainda não conseguimos entender exatamente como ele funciona. Ainda estamos estudando.

Lembrando sempre que somos principiantes em conexão com Oracle (mesmo qualquer outro). Até hoje somente com DBF's.

No nosso "trio" temos duas pessoas que conhecem o funcionamento do Oracle, mas na hora de fundir o Oracle com o xHarbour eu ainda tenho muitas dificuldades. Estes primeiros passos estão representando um grande aprendizado e cheio de dificuldades.
Certamente com a ajuda dos colegas conseguiremos superar esta etapa também.

Obrigado.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
ANDRIL
Usuário Nível 5
Usuário Nível 5
Mensagens: 1299
Registrado em: 06 Jul 2004 00:44
Contato:

Oracle - gravar dados

Mensagem por ANDRIL »

Hasse, não trabalho com oracle, e sim com mysql com php, tente fazer com esta sintexe:

Código: Selecionar todos

cUpd := "update PRESCR_LAB_INTEGRACAO_V set DS_INTEGRACAO='YYYYYYYYYYYY' where NR_PRESCRICAO = 1450163"
oCommand:CommandText:=cUpd
oCommand:Execute()
Nota1 : YYYYYYYYYYYY esta demilitado por aspas simples 'YYYYYYYYYYYY'
Nota2 : estou assumindo que o campo NR_PRESCRICAO seja numerico no BD. Se for caracter, coloque NR_PRESCRICAO='1450163' entre aspas simples '

Boa sorte.
Clipper 5.2e / Blinker 5.1 / Harbour 3.2 / GTwvg
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Bom dia Andril.

Amanhã tentarei a tua sugestão.
Obrigado.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Hasse
Usuário Nível 4
Usuário Nível 4
Mensagens: 820
Registrado em: 19 Out 2004 10:30
Localização: Jaraguá do Sul - SC

Oracle - gravar dados

Mensagem por Hasse »

Boa tarde Andril e demais colegas.

Ontem à tarde testamos a tua sugestão e obtivemos sucesso. Agradecemos a todos aqueles que direta ou indiretamente contribuiram, mas especialmente ao colega Andril.

Entretanto prevejo que o meu aprendizado deverá ser longo.

Apesar de haver conseguido conectar ao Banco em rede local, na conexão via VPN ainda estou com problemas. Ela relata "Falha no conexão ao Servido. TNS: ocoreu timeout da conexão."

Mais algumas dúvidas:

1)-Objeto oRecordSet x oCommand:
Foi pelo oRecorSet que conseguimos ler dados do Banco.
E somente pelo oCommand que conseguimos escrever no Banco.
Com o oRecordSet NÃO conseguimos escrever. É assim mesmo ?

2)-No código abaixo:

Código: Selecionar todos

Cmd1.CommandText = "sp_AdoTest"
Cmd1.CommandType = adCmdStoredProc
Cmd1.putActiveConnection( Conn1 );
Cmd1.putCommandText     ( bstrSP );
Cmd1.putCommandType     (msado15.CommandTypeEnum.adCmdStoredProc);
Qual a diferença entre eles ?
Qual a finalidade de cada um ?

3)-Em quais situações usa-se o código abaixo:

Código: Selecionar todos

cTheQuery := "UPDATE ENF.BENF3106_FUSION SET "+ cSet +" WHERE INSCIPTU = " + Transforme( nInscIPTU )
oConnection:BeginTrans()
oConnection:Execute( cTheQuery )
oConnection:CommitTrans()
4)-Stored Procedure:
Alguém poderia me ceder um pequeno exemplo de funcionamento desta Stored Procedure ?
Se possível comentado, para facilitar o meu aprendizado.

Antecipadamente grato.
Hasse
CP200 / CP500 / Basic / dBase III / dBase IV / Clipper Summer / RTlink / Exospace.
Clipper 5.3b / Blinker 7.0 / CDX com TAG
xHarbour 1.2.1-6604 / Borland C++ (5.5.1) 32 bit / HBmake.
Harbour 3.2.0dev (r1412121623) / MINGW / HBM2 / MiniGui HMG 3.1.4 / IDE (Roberto Lopez).
"Conheça todas as teorias, domine todas as técnicas, mas, quando tocares uma alma humana, seja apenas outra alma humana." (C.G.Jung)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Oracle - gravar dados

Mensagem por asimoes »

Exemplo simples com StoredProcedure em Harbour

Tá aqui fora porque não pode usar tamanho de fonte dentro de code
cConexao:="Provider=OraOLEDB.Oracle;Data Source=DS01;UserID=aluno;Password=aluno;FetchSize=100;CacheType=Memory;PLSQLRSet=True;"

Código: Selecionar todos

#include "hbcompat.ch"
#include "inkey.ch"
#include "setcurs.ch"
#include "error.ch"
#include "achoice.ch"
#include "fileio.ch"
#include "common.ch"
#include "dbinfo.ch"
#include "hbver.ch"
#include "hbdyn.ch"
#include "wvtwin.ch"
#include "hbgtinfo.ch"
#include "hbgtwvg.ch"
#include "wvgparts.ch"
#include "hbcompat.ch"
#include "windows.ch"
#include "adordd.ch"

[size=85]
FUNCTION MAIN
Local oConnection := Win_OleCreateObject( "ADODB.connection" )
cConexao:="Provider=OraOLEDB.Oracle;Data Source=DS01;UserID=aluno;Password=aluno;FetchSize=100;CacheType=Memory;PLSQLRSet=True;"
           oConnection:Open(cConexao)
           oCommand:=CriaObjetoCommand(@oCommand) 
           oCommand:ActiveConnection:=oConnection

           *--------------------------------------------------------------------------------------------------
           * Exemplo 1 SP retorno de fun‡Æo
           *--------------------------------------------------------------------------------------------------           
           
           cls
           
           oCommand:=Nil
           oCommand:=CriaObjetoCommand(@oCommand) 
           oCommand:ActiveConnection:=oConnection
           strSQL:= "vitorteste.retornaa"
           oCommand:CommandText:= strSQL 
           oCommand:CommandType:= adCmdStoredProc
           Param0 := oCommand:CreateParameter("p_sRetorno", adVarChar, adParamOutput,4000)
           oCommand:Parameters:Append( Param0)	   
           oCommand:Execute()
           X:=oCommand:Parameters(0):Value
           MsgInfo(x) 
		   
           *--------------------------------------------------------------------------------------------------
           * Exemplo 2 SP retorno de função
           *--------------------------------------------------------------------------------------------------
            oCommand:=Nil
            oCommand:=CriaObjetoCommand(@oCommand) 
            strSQL := "CORPORATIVO.UTILITARIO.STRZERO"
            oCommand:CommandText:= strSQL
            Param0 := oCommand:CreateParameter("result", adVarChar, adParamReturnValue,100)
            oCommand:Parameters:Append( Param0)
         
           Param1 := oCommand:CreateParameter("p_nnumero", adNumeric, adParamInput,10,1)
           oCommand:Parameters:Append( Param1 )

           Param2 := oCommand:CreateParameter("p_ntamanho", adNumeric, adParamInput,10,10)
           oCommand:Parameters:Append( Param2 )
		   
           oCommand:Execute()
          
           X:=oCommand:Parameters(0):Value
		   
           MsgInfo(X) 
          
           *--------------------------------------------------------------------------------------------------
           * Exemplo 3 SP retorno de cursor
           *--------------------------------------------------------------------------------------------------
           oCommand:=Nil
           oCommand:=CriaObjetoCommand(@oCommand) 
           oCommand:ActiveConnection:=oConnection
           
           strSQL := "CORPORATIVO.BAIRRO_PAC.BUSCA_LISTA_TODOS"
           oCommand:CommandText:= strSQL
		   
           Param1 := oCommand:CreateParameter("p_serro", adVarChar, adParamOutput,2000)
           oCommand:Parameters:Append( Param1 )

           cRecordSet:=oCommand:Execute()
           aResulta:={}

           DO WHILE ! cRecordSet:Eof
              cCampo1:=cRecordSet:Fields( 6 ):value
              cCampo2:=cRecordSet:Fields( 4 ):value
              cCampo3:=cRecordSet:Fields( 5 ):value

              IF ValType(cCampo1) $ "ND"
                 cCampo1:=IF(ValType(cCampo1)=="N", Str(cCampo1),DTOC(cCampo1))
              ENDIF
              IF ValType(cCampo2) $ "ND"
                 cCampo2:=IF(ValType(cCampo2)=="N", Str(cCampo2),DTOC(cCampo2))
              ENDIF              
              IF ValType(cCampo3) $ "ND"
                 cCampo3:=IF(ValType(cCampo3)=="N", Str(cCampo3),DTOC(cCampo3))
              ENDIF              

              IF ValType(cCampo1) $ "U"
                 cCampo1:=""
              ENDIF
              IF ValType(cCampo2) $ "U"
                 cCampo2:=""
              ENDIF
              IF ValType(cCampo3) $ "U"
                 cCampo1:=""
              ENDIF
             
              AADD(aResulta,cCampo1+" "+cCampo2+" "+cCampo3)
              cRecordSet:MoveNext()
           ENDDO

           Achoice(00,00,24,79,aResulta)

           *--------------------------------------------------------------------------------------------------
           * Exemplo 4 retorno de query com retorno de função
           *--------------------------------------------------------------------------------------------------

           cls
           
           oRecordSet:=Nil
           CriaObjetoRecordSet(@oRecordSet)
           oRecordSet:CursorType := adOpenDynamic
           //oRecordSet:MaxRecords:= 10
           oRecordSet:CacheSize:= 100
           //oRecordSet:CursorLocation := adUseClient
           oRecordSet:ActiveConnection:=oConnection          

           TheQuery:="SELECT corporativo.utilitario.strzero(2,10) FROM DUAL"
           
           oRecordSet:Source := TheQuery

           oConnection:Execute( TheQuery ) 
        
           oRecordSet:Open()
        
           oRecordSet:MoveFirst()
        
           aResulta:={}

           DO WHILE ! oRecordSet:Eof
              cCampo1:=oRecordSet:Fields( 0 ):value
              AADD(aResulta,cCampo1)
              oRecordSet:MoveNext()
           ENDDO

           Achoice(00,00,24,79,aResulta)

RETURN Nil

FUNCTION CriaObjetoCommand(oObjeto)
LOCAL oObjetoCommand:=Win_OleCreateObject( "ADODB.Command" )
   IF oObjeto!=Nil
      oObjeto:=Nil
   ENDIF
   oObjeto:=oObjetoCommand
RETURN oObjetoCommand

FUNCTION CriaObjetoRecordSet(oObjeto)
LOCAL oObjetoRecordSet:=Win_OleCreateObject( "ADODB.recordset" )
   IF oObjeto!=Nil
      oObjeto:=Nil
   ENDIF
   oObjeto:=oObjetoRecordSet
RETURN oObjetoRecordSet
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Oracle - gravar dados

Mensagem por asimoes »

3)-Em quais situações usa-se o código abaixo:

Hasse, a instrução sql é para atualizar dados de uma tabela.

Note que temos o controle de transação BeginTrans() e CommitTrans() para efetivar a gravação no banco.
Pode colocar em bloco de TRY..CATH

Código: Selecionar todos

TRY 
    cTheQuery := "UPDATE ENF.BENF3106_FUSION SET "+ cSet +" WHERE INSCIPTU = " + Transforme( nInscIPTU )
   oConnection:BeginTrans()
   oConnection:Execute( cTheQuery )
   oConnection:CommitTrans()
CATCH
   oConnection:RollbackTrans() //Em caso de erro desfaz modificações pendentes
END
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Responder