Jump to content
Fivewin Brasil

SQLRRD create table(Mysql)


tiagojb

Recommended Posts

Olá a todos.
Estou fazendo testes com a sqlrdd, quanto a criação de tabelas via comando SQL nativo.
Porém estou enfrentando a seguinte situação:

Ao tentar executar:

cSql :="CREATE TABLE country (CODE char(3), NAME char(50));"
apCode := SR_SQLParse( cSql )
oSql := SR_GetConnection()
oSql:exec( SR_SQLCodeGen( apCode, , oSql:nSystemID ) ) 

Em meu programa, não é executada a ação no DB (MySQL), quando executo comandos como SELECT, UPDATE, INSERT, consigo fazê-lo normalmente.

Recebo o seguinte error.log de minha aplicação:

Descricao do erro: Erro SR_ODBC/0  SQLExecDirect Error
HY090 - 0 - [Microsoft][ODBC Driver Manager] Comprimento inválido de seqüência de caracteres ou de buffer
Command sent to database : 

Steatment handle  :    3873144
Connection handle :    3871560
RetCode           :         -1
 - RollBack executed.

Alguém teria algum sugestão?

Link to comment
Share on other sites

Bom dia Tiago

Já tentou usar a sqlExecute ?

No seu caso, ficaria algo do tipo:

cSql :="CREATE TABLE country (CODE char(3), NAME char(50));"
oSql := SR_GetConnection()                                  
sqlExecute( cSql,nil,oSql:nSystemID )

Eduardo, fiz o teste utilizando sqlExecute conforme me informou.

Testei acionando os comandos que passou após a conexão ao Mysql via ODBC ser efetuada e não criou a tabela,

Testei acionando os comandos que passou após uma consulta efetuada com sucesso e também não criou a tabela.

Se entro no mysql query tool e digito a mesma instrução sql que informou ele cria normalmente a tabela.

Link to comment
Share on other sites

Eita coisa doida hauhauha

Particularmente eu não uso o sqlExecute da maneira que te mandei, apenas vi os parâmetros e adaptei ao código que postou anteriormente.

Eu estabeleço a conexão ao entrar no sistema e simplesmente chamo o sqlExecute( cQuery )

Uma outra forma de se criar a tabela, é usando o DBCREATE().

Você já tentou esse comando ?

Link to comment
Share on other sites

boa noite, no exemplo a seguir tem uma rotina que cria a tabela com sqlrdd , talvez te ajude.

William

***********************************************************  
** Arquivo....: TConnectionManager                       **  
** Função.....:                                          **  
** Autor......: Valter Junior                            **  
** Data/Hora..: 03/02/2011 00:04:13                      **  
** Observações:                                          **  
**                                                       **  
***********************************************************  
# include "FiveWin.ch"
# include "sqlrdd.ch"
# include "HBXml.ch"

#IFDEF _POSTGREESQL_
   # include "pgs.ch"
#ENDIF

#IFDEF _MYSQL_
   # include "mysql.ch"
#ENDIF

#IFDEF _ORACLE_
   # include "oracle.ch"
#ENDIF

#IFDEF _FIREBIRD_
   # include "firebird.ch"
#ENDIF

REQUEST SQLRDD
REQUEST SQLEX
REQUEST SR_ODBC


#IFDEF _POSTGREESQL_
   REQUEST SR_PGS 
#ENDIF

#IFDEF _MYSQL_
   REQUEST SR_MYSQL
#ENDIF

#IFDEF _ORACLE_
   REQUEST SR_ORACLE
#ENDIF

#IFDEF _FIREBIRD_
   REQUEST SR_FIREBIRD
#ENDIF

# define RDD_NAME "SQLRDD"

CLASS TConnectionManager

   PRIVATE:
   
      DATA nActiveHandle
      DATA aActiveConnections
      DATA cFile
      DATA nIdDataBase
      DATA aFieldsIncrements
      DATA cDatabase
      DATA cSQL
      
   PUBLIC:
   
      METHOD new( cFile ) CONSTRUCTOR
      METHOD createConnection( cName, nIdDataBase, cHost, cDatabase, cUser, cPassword, cTns )
      METHOD saveConnection( cName, nId, cString )
      METHOD openConnection( cName )
      METHOD connectionExists( cName )
      METHOD end()
  
      METHOD getHandle()                        INLINE ::nActiveHandle
      METHOD getConnection()                    INLINE SR_GetConnection( ::nActiveHandle )
      METHOD beginTransaction()                 INLINE SR_BeginTransaction( ::nActiveHandle )
      METHOD endTransaction()                   INLINE SR_EndTransaction( ::nActiveHandle )
      METHOD roolBack()                         INLINE SR_RollBackTransaction( ::nActiveHandle )
      METHOD tableExists( cTable )              INLINE SR_ExistTable( cTable )
      METHOD createTable( cTable, aStruct )
      METHOD convertSql( cSql, aParams )
      METHOD getSystemId()                      INLINE ::nIdDatabase
      METHOD getPath()                          INLINE ::cFile
      METHOD FormatSql( aField )
      METHOD createSequence()
      METHOD getSQLParse()                      INLINE ::cSQL
      METHOD quotedStr( xValue )                INLINE SR_SQLQuotedString( xValue, ::nIdDatabase )
      METHOD toTable( cSql, aParams, cAlias )
      METHOD toArray( cSql, aParams )
      
      METHOD getOdbcId()                        INLINE CONNECT_ODBC
      METHOD getPostgreId()                     INLINE CONNECT_POSTGRES
      METHOD getMysqlId()                       INLINE CONNECT_MYSQL
      METHOD getOracleId()                      INLINE CONNECT_ORACLE
      METHOD getFireBirdId()                    INLINE CONNECT_FIREBIRD
      
ENDCLASS

/*  
 * Construtor  
 * 07/02/2011 - 21:26:20  
 */  
METHOD new( cFile ) CLASS TConnectionManager

   IF empty( cFile )
      msgStop( "Arquivo xml não foi informado", "Erro" )
      RETURN
   ENDIF

   ::aActiveConnections := {}
   ::aFieldsIncrements  := {}
   ::cFile              := cFile

RETURN Self
      
/*  
 * Criar uma nova conexão ou abrir caso já existe, e gravar no arquivo xml  
 * 07/02/2011 - 21:29:46  
 */  
METHOD createConnection( cName, nIdDatabase, cHost, cDatabase, cUser, cPassword, cTns ) CLASS TConnectionManager
LOCAL cString
DEFAULT cTns := ""

switch( nIdDatabase )

   CASE CONNECT_ODBC
   
      cString := ""
      EXIT
   
   CASE CONNECT_POSTGRES
   
      cString := "ConnString = pgs=" + cHost + ";uid=" + cUser + ";dtb="+ cDatabase + ";pwd=" + cPassword
      EXIT
      
   CASE CONNECT_MYSQL

      cString := "ConnString = MySQL=" + cHost + ";UID=" + cUser + ";PWD=" + cPassword + ";DTB=" + cDatabase
      EXIT

   CASE CONNECT_ORACLE

      cString := "ConnString = OCI=" + cHost + ";UID=" + cUser + ";PWD=" + cPassword + ";TNS=" + cTns + ";"
      EXIT

   CASE CONNECT_FIREBIRD
   
      DEFAULT cTns := "ISO8859_1"
      cString := "ConnString = FIREBIRD=" + cHost + ":e:" + cDatabase + ";uid=" + cUser + ";pwd=" + cPassword + ";charset=" + cTns
      EXIT
   
END

::nActiveHandle := SR_AddConnection( nIdDatabase, cString )

IF ::nActiveHandle < 0
   msgStop( "Erro ao conectar com o banco de dados " + cDatabase + "!", "Erro" )
   RETURN -1
ENDIF

aAdd( ::aActiveConnections, ::nActiveHandle )

IF ! ::connectionExists( cName )
   ::saveConnection( cName, nIdDatabase, cString )
ENDIF

::nIdDatabase := nIdDatabase
::cDataBase   := cDatabase

RETURN ::nActiveHandle

/*  
 * Salvar uma conexão no arquivo xml identificando com um alias
 * 07/02/2011 - 21:29:46  
 */  

METHOD saveConnection( cName, nId, cString ) CLASS TConnectionManager
LOCAL nFileHandle,;
      oXml       ,;
      oFile
      
oFile := TTxtFile():new( ::cFile )

IF FError() > 0
   msgStop( "Erro ao criar arquivo " + ::cFile )
   RETURN .F.
ENDIF

oXml := TXmlNode():new( nil, cName, nil, "" )

oXml:setAttribute( "IDConnection"    , alltrim( str( nId ) ) )
oXml:setAttribute( "StringConnection", alltrim( cString )    )

oXml:write( oFile:hFile, HBXML_STYLE_INDENT + HBXML_STYLE_THREESPACES )
oFile:end()

RETURN

/*  
 * Abre uma conexão salva apartir de um alias
 * 07/02/2011 - 21:29:46  
 */  

METHOD openConnection( cName ) CLASS TConnectionManager
LOCAL oXml
LOCAL nFileHandle
LOCAL oNode
      
nFileHandle := FOpen( ::cFile )

IF FError() > 0
   msgStop( "Não foi possível abrir o arquivo " + ::cFile, "Erro" )
   RETURN
ENDIF

oXml := TXmlDocument():new( nFileHandle )

IF oXml:nStatus <> HBXML_STATUS_OK
   msgStop( "Arquivo " + ::cFile + " não é um xml válido", "Erro" )
   oXml:end()
   RETURN -1
ENDIF

oNode := oXml:findFirst( cName )

IF oNode <> nil

   ::nActiveHandle := SR_AddConnection( val( oNode:getAttribute( "IDConnection" ) ), oNode:getAttribute( "StringConnection" ) )
   ::nIdDatabase   :=  val( oNode:getAttribute( "IDConnection" ) )
   
   IF ::nActiveHandle < 0
      msgStop( "Erro ao conectar com o banco de dados!", "Erro" )
      RETURN -1
   ENDIF
   
   aAdd( ::aActiveConnections, ::nActiveHandle )   
   
ELSE
   msgStop( "Conexão não encontrada", "Erro" )
   RETURN -1
ENDIF

FClose( nFileHandle )

RETURN ::nActiveHandle

/*  
 * Checa se uma conexão já foi salva anteriormente através de uma alias
 * 07/02/2011 - 21:29:46  
 */  

METHOD connectionExists( cName ) CLASS TConnectionManager
LOCAL nFileHandle,;
      oXml,;
      oNode,;
      lResult

nFileHandle := FOpen( ::cFile )

IF FError() > 0
   RETURN .F.
ENDIF

oXml := TXmlDocument():new( nFileHandle )

IF oXml:nStatus <> HBXML_STATUS_OK
   oXml:end()
   RETURN .F.
ENDIF

oNode := oXml:findFirst( cName )

lResult := oNode <> nil

RETURN lResult

/*
 * Criar tabela no banco
 * 21/02/2011 - 21:45:47 
 */
METHOD createTable( cTable, aStruct ) CLASS TConnectionManager

   LOCAL nCont, cSql

   cSql := "CREATE TABLE " + cTable + "( "

   FOR nCont := 1 TO Len( aStruct )
      cSql += ::FormatSql( aStruct[nCont] ) + ", "
   NEXT

   If ::getSystemId() == CONNECT_MYSQL

      cSql += "sr_recno bigint(15) NOT NULL unique auto_increment, "

   ElseIf ::getSystemId() == CONNECT_ORACLE

     cSql += "sr_recno number(15) NOT NULL, "
      aAdd( ::aFieldsIncrements, { cTable, "sr_recno" } )

   Endif   

   cSql += "sr_deleted char(1) default ' ' NOT NULL ) "

   ::getConnection():execute( cSql )
   
   If ::getSystemId() == CONNECT_ORACLE
     ::createSequence()
   Endif

RETURN

/*
 * Retorna string com instrução SQL para a criação dos campos
 * 21/02/2011 - 21:45:47 
 */
METHOD FormatSql( aField ) CLASS TConnectionManager

LOCAL cSql := "", cField := "", lAutoIncrement

   cField1 := Alltrim( Str( aField[ 3 ] ) )
   cField2 := Alltrim( Str( aField[ 4 ] ) )
   lAutoIncrement := if( aField[12] == nil, .F., aField[12] )

   If ::getSystemID() == CONNECT_MYSQL

      IF aField[ 2 ] == "C"
            
         IF val(cField1) > 255

            cSql := "blob"
               
         ELSE
         
            cSql := "char(" + cField1 + ") default ' ' NULL "
            
         ENDIF
            
      ELSEIF aField[ 2 ] == "N"
         
         IF lAutoIncrement

            IF ::getSystemId() == CONNECT_MYSQL
         
               cSql := "int(" + cField1 + ") NOT NULL auto_increment, "
         
            ELSEIF ::getSystemId() == CONNECT_ORACLE
         
              cSql += "number(" + cField1 + ") NOT NULL, "
               aAdd( ::aFieldsIncrements, { cTable, aField[1] } )
         
            ENDIF
            
         ELSE
            cSql := "decimal(" + cField1 + "," + cField2 + ") default '0' NULL "
         ENDIF

      ELSEIF aField[ 2 ] == "D"
         cSql := "date default '0001-01-01' NULL"

      ELSEIF aField[ 2 ] == "L"
         cSql := "tinyint(" + cField1 + ") default '0' NULL"
         
      ELSEIF aField[ 2 ] == "M"
         cSql := "blob"
               
      ENDIF

  ElseIf ::getSystemID() = CONNECT_ORACLE

      IF aField[ 2 ] == "C"
            
         IF val(cField1) > 255

            cSql := "clob default ' ' NULL"
               
         ELSE
         
            cSql := "char(" + cField1 + ") default ' ' NULL"
            
         ENDIF
            
      ELSEIF aField[ 2 ] == "N"
         cSql := "number(" + cField1 + "," + cField2 + ") default '0' NULL"

      ELSEIF aField[ 2 ] == "D"
         cSql := "date"     

      ELSEIF aField[ 2 ] == "L"
         cSql := "integer default '0' NULL"
         
      ELSEIF aField[ 2 ] == "M"
         cSql := "clob default ' ' NULL"
            
      ENDIF
  
  Endif

RETURN if( !empty( cSql ), Lower( aField[ 1 ] ) + " " + cSql, "" )

METHOD createSequence() CLASS TConnectionManager
LOCAL nCont,;
      cSql ,;
      cTable,;
      cField

FOR nCont := 1 TO len( ::aFieldsIncrements )

   cTable    := ::aFieldsIncrements[nCont,1]
   cField    := ::aFieldsIncrements[nCont,2]

   cSql := "CREATE OR REPLACE SEQUENCE " + ::cDatabase + "." + cTable + "_SQ"
   cSql += " START WITH 1"
   cSql += " MAXVALUE 999999999999999999999999999"
   cSql += " MINVALUE 1"
   cSql += " NOCYCLE"
   cSql += " CACHE 20"
   cSql += " NOORDER"
   ::getConnection():execute( cSql )

   cSql := "CREATE OR REPLACE FUNCTION " + ::cDatabase + "." + cTable + "_SP RETURN"
   cSql += " NUMBER AS ID_R NUMBER;"
   cSql += " BEGIN SELECT " + cTable + "_SQ.NEXTVAL INTO ID_R FROM DUAL;"
   cSql += " RETURN ID_R; END;"
   ::getConnection():execute( cSql )

   cSql := "CREATE OR REPLACE TRIGGER " + ::cDatabase + "." + cTable + "_SR BEFORE"
   cSql += " INSERT ON " + SR_SQLQuotedString( Upper(cTable), ::getSystemId() ) + " FOR EACH ROW"
   cSql += " DECLARE v_seq " + SR_SQLQuotedString( Upper(cTable), ::getSystemId() ) + "." + cField + "%TYPE;"
   cSql += " BEGIN If :OLD." + cField + " IS NULL THEN"
   cSql += " SELECT " + cTable + "_SQ.NEXTVAL INTO v_seq FROM DUAL;"
   cSql += " :NEW." + cField + " := v_seq; END IF; END;"
   ::getConnection():execute( cSql )

NEXT

RETURN

METHOD convertSql( cSql, aParams ) CLASS TConnectionManager

::cSql := SR_SQLCodeGen( SR_SQLParse( cSql ), aParams )

RETURN ::cSql

METHOD end() CLASS TConnectionManager

   SR_EndConnection( ::nActiveHandle )

RETURN

METHOD toTable( cSql, aParams, cAlias ) CLASS TConnectionManager

::getConnection():exec( ::convertSql( cSql, aParams ),, .T.,, cAlias )

RETURN

METHOD toArray( cSql, aParams, lAssociativo ) CLASS TConnectionManager
LOCAL nCont, nCont2, aHash, aResult := {}, aAux := {}

DEFAULT lAssociativo := .F.

IF cSql == NIL .OR. Empty( cSql )

*//   Throw( ErrorNew( "CONEXAO", 0, ++::nContException, ProcName(), "Instrução SQL requerida." ) )
     MsgAlert("Instrução SQL requerida, observe a chamada na " + ProcName(),"Verifique" )
   Return aRetorno  

ENDIF

IF lAssociativo

   ::getConnection():exec( ::convertSql( cSql, aParams ),, .T., @aAux )

// criando hash!

   FOR nCont := 1 To LEN( aAux )

      aHash := hash()
      
      FOR nCont2 := 1 TO len( ::getConnection:aFields )

         aHash[ Lower( ::getConnection:aFields[ nCont2, 1] ) ] := aAux[nCont, nCont2]

      NEXT

      aAdd( aResult, aHash )

   NEXT

ELSE

   ::getConnection():exec( ::convertSql( cSql, aParams ),, .T., @aResult )

ENDIF

RETURN aResult


Link to comment
Share on other sites

Eita coisa doida hauhauha

Particularmente eu não uso o sqlExecute da maneira que te mandei, apenas vi os parâmetros e adaptei ao código que postou anteriormente.

Eu estabeleço a conexão ao entrar no sistema e simplesmente chamo o sqlExecute( cQuery )

Uma outra forma de se criar a tabela, é usando o DBCREATE().

Você já tentou esse comando ?

Testei com dbcreate e foi criada a tabela DBF na pasta de meu executável.

Estes são os Request iniciais do executável, após isto vema rotina de conexão via ODBC com o Mysql e o comando dbcreate()

REQUEST SQLEX              // SQLRDD Extreme should be linked in
REQUEST SR_ODBC            // Needed if you plan to connect with ODBC
REQUEST SR_MYSQL  

// acesso via ODBC (rede interna)
cDSN:= "USR=root;PWD=root;DTB=test;DSN=test;driver=MySQL ODBC 3.51 Driver;" 
nCnn := SR_AddConnection(1,cDSN)

nErr=''
nPos=''
If nCnn < 0
  ? "Connection error. See sqlerror.log for details."
  Quit
EndIf

   SR_UseDeleteds( .T. )     // .f.= NÃO MANTER REGISTROS DELETADOS NAS TABELAS .t. manter
   SR_SetFastOpen(.T.)       // ABRE AS TABELAS EM MODO COMPARTILHADO
   SR_SetGoTopOnScope(.F.)   // NÃO EXECUTA O DBGOTOP() AUTOMATICO NOS ORDSCOPE
   SR_MaxRowCache( 100 )     // Determina o tamanho máximo teórico do cache de linhas da workarea
   SR_SetBaseLang( 2 )       // portugues
   SR_Msg(2)                 // portugues
   SR_SETSYNTHETICINDEX(.F.) // Força que os próximos índices criados sejam sintéticos(porem os indice ficam por conta apenas do SQLRDD)
   SR_SETSYNTHETICINDEXMINIMUN(10) //Configura a quantidade mínima de colunas na chave de índice para criá-lo como Sintético

DbCreate( "CARTES", { { "TEXTO", "C", 100, 0 } } )
Link to comment
Share on other sites

country, code e name, não são palavras resevadas???

Se for não vai funcionar mesmo e deveria dar erro.

Só um palpite, talves sirva.

É um bom palpite sim, porém tentei criar com sqlexecute e com oSql:exec( ) várias tabelas por exemplo:

cSql :="CREATE TABLE CARTA (sr_recno bigint(15) NOT NULL unique auto_increment, CODE char(3), NAME char(50), sr_deleted char(1) default ' ' NOT NULL );"

E mesmo assim não é criada a tabela no MySQL, e se eu executo o DbCreate() ele cria um DBF na pasta do executável.

Link to comment
Share on other sites

William Adami,

analisando seu código percebi que você usa a função oSql:exec();

Tentei adaptar ela a que tinha usado no incio do tópico e gerou o mesmo erro do inicio do tópico ao executar a aplicação.

Utilizei da seguinte maneira:

cSql :="CREATE TABLE CARTA (sr_recno bigint(15) NOT NULL unique auto_increment, CODE char(3), NAME char(50), sr_deleted char(1) default ' ' NOT NULL );"

apCode := SR_SQLParse( cSql )
oSql := SR_GetConnection()
oSql:exec( SR_SQLCodeGen( apCode, , oSql:nSystemID ),, .T.,nil )

Porém obtive o erro ao executar a aplicação:

  Descricao do erro: Erro SR_ODBC/0  SQLExecDirect Error
HY090 - 0 - [Microsoft][ODBC Driver Manager] Comprimento inválido de seqüência de caracteres ou de buffer
Command sent to database : 

Steatment handle  :    3873144
Connection handle :    3871560
RetCode           :         -1
 - RollBack executed.
   Argumentos:

Stack Calls
===========
   Called from:  => THROW(0)
   Called from: ..\..\source\sqlconnection.prg => SR_ODBC:RUNTIMEERR(861)
   Called from: ..\..\source\sqlconnection.prg => SR_ODBC:EXEC(367)

E seguinte errosql.log:

16/10/2013 09:02:01: SQLExecDirect Error
HY090 - 0 - [Microsoft][ODBC Driver Manager] Comprimento inválido de seqüência de caracteres ou de buffer
Command sent to database : 

Steatment handle  :    3873144
Connection handle :    3871560
RetCode           :         -1
	SR_ODBC:RUNTIMEERR     Linha : 859
SR_ODBC:EXEC     Linha : 367
TESTE     Linha : 189
INICIO     Linha : 46
(b)TELAO     Linha : 39
TWINDOW:ACTIVATE     Linha : 959
TELAO     Linha : 39
MAIN     Linha : 11	

Link to comment
Share on other sites

Pessoal consegui resolver, estava executando a função: SR_SQLParse e SR_SQLCOdeGen, desabilitei estas funções na criação da tabela e executou com sucesso, fiquei sem entender, porém funcionou.

Segue abaixo o código correto e as linhas que comentei que estavam causando o erro:

cSql :="CREATE TABLE CARTA (sr_recno bigint(15) NOT NULL unique auto_increment, Campo1 char(3), campo2 char(50), sr_deleted char(1) default ' ' NOT NULL );"
//apCode := SR_SQLParse( cSql )
oSql := SR_GetConnection()
//cSql  := SR_SQLCodeGen( apCode, ,oSql:nSystemID )
?oSql:exec( cSql,,.T. )

Agradeço a todos pelo empenho e grande auxílio.

Link to comment
Share on other sites

Olá Tiago, o seguinte código funciona bem , está criando a tabela normalmente, teste aí:


function criatabela()
  local osql
,csql
  oSql := SR_GetConnection() 
  cSql :="CREATE TABLE CARTA (sr_recno bigint(15) NOT NULL unique auto_increment, CODE char(3), NAME char(50), sr_deleted char(1) default ' ' NOT NULL );"
  oSql:Exec( csql )
 

return nil

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...