Macro Libreoffice Calc salvando BD Base Hora

Saudações pessoal, estou com dificuldades para salvar uma variável com o resultado do TimeSerial().

sBancoDados = caminho & "BLV.odb" '<< Nome do banco de dados registrado'
oDBC = createUnoService( "com.sun.star.sdb.DatabaseContext" ) 
oConexao = oBD.getConnection( "","" )
oDeclaracao = oConexao.createStatement()

sCampos = " ""var1""  "
Dia = DateSerial(2021,10,17)
Hora = TimeSerial(21,16,00)

sSQL = "INSERT INTO" & sNome_Tabela & "(" & sCampos & ") VALUES (" & Dia & ")"
oDeclaracao.executeUpdate( sSQL )

fiz uma tabela no BD para testar os diversos tipos de variável , quando eu seleciono a variável Dia consigo fazer entrada no BD, entretanto quando seleciono a variável Hora, ele retorna erro ao tentar inserir no BD onde contém os campos var1, var2, var3, … que criei para cada um dos tipos existentes: BigInt, Number, Decimal …

a macro retorna o seguinte erro ao selecionar a variável dia:
Erro de execução do BASIC.
Ocorreu uma exceção
Type: com.sun.star.sdbc.SQLException
Message: firebird_sdbc error:
*Dynamic SQL Error
*SQL error code = -804
*Count of read-write columns does not equal count of values
caused by
‘isc_dsql_prepare’

Alguém já teve essa dificuldade ?
Vocês podem verificar que o tratamento da variável está sendo realizada como um número, isso se deve porque não consegui entrar como uma campo timestamp, ou separados como um campo para data e outro para hora, como acredito seria o correto.

1 Like

A mensagem indica que a contagem de colunas leitura+escrita do BD não é igual à contagem de valores enviados para gravação. No meu entender, um dos valores não pode ser gravado no BD por que seu BD tem pelo menos uma coluna somente leitura.

ohallot, primeiramente obrigado pela sua resposta.
A variável que seleciona os campos da tabela para inserir o valor no BD é a “sCampos” no código, o valor dela é:
sCampos = " ""var1"" "
o BD possui os campos
var1 do tipo BigInt
var2 do tipo Number
var3 do tipo Decimal
var4 do tipo Integer
var4 do tipo Float
var6 do tipo Double
var7 do tipo Date
var8 do tipo Time
var9 do tipo Date/Time
todas elas são para entrada não obrigatória e são para entrada de valores (não apenas leitura).

uma outra alternativa que tentei foi transformar os valores de hora e dia em string, dessa forma ficaria
Dim Dia As Double
Dim Hora As Double
Dim sValores As String

sNome_Tabela = " ""TesteVar"" " '<< Nome da tabela'
'nesta tabela o campo var10 está configurado como text [varchar] com comprimento 100
    sCampos = " ""var10""  "
Dia = DateSerial(2021,7,30)
Hora = TimeSerial(21,16,00)
sValores = Cdate(Dia + Hora)

sSQL = "INSERT INTO" & sNome_Tabela & "(" & sCampos & ") VALUES (" & sValores & ")" 
oDeclaracao.executeUpdate( sSQL )

mas ainda sim permaneceu o erro

Erro de execução do BASIC.
Ocorreu uma exceção
Type: com.sun.star.sdbc.SQLException
Message: firebird_sdbc error:
*Dynamic SQL Error
*SQL error code = -104
*Token unknown - line 1, column 56
*21
caused by
‘isc_dsql_prepare’

Todos os valores em SQL devem estar em forma de texto.

INSERT INTO “Table1” (“f_time”) VALUES (‘13:58:01’)

elmau, obrigado pela sua resposta. Entretanto não parece ser o problema, pois quando eu altero para a o resultado da variável “dia” a macro consegue fazer entrada no BD, já quando tento entrar com a hora o BD retorna o erro relatado. A única alteração que existe entre as variáveis é o valor, entretanto as duas é do mesmo tipo Double , que, segundo a ajuda do LibreOffice :

A função DateSerial retorna o tipo de dado Variant com VarType 7 (Date). Internamente, esse valor é armazenado como um valor Double

Que é justamente o tipo declarado para as variáveis dia e hora .
Mas, também para tirarmos a dúvida fiz conforme sua orientação:

‘-----------------------------------------------------------------------------------------
Sub Grava()’ tempo , contUG as Double , energUg as Integer, UnidadeGer as string )
Dim oDBC As Object
Dim oBD As Object
Dim oConexao As Object
Dim oDeclaracao As Object
'VJFE52F11X-B1212S
Dim sBancoDados As String
Dim sSQL As String
Dim Dia As Double
Dim Hora As Double
Dim sValores As String
'fazendo aquisicao do caminho que se encontra a planilha e BD
GlobalScope.BasicLibraries.loadLibrary(“Tools”)
caminho = ConvertTOUrl( Tools.Strings.DirectoryNameoutofPath(ThisComponent.url, “/”) ) & “/”
sBancoDados = caminho & “BLV.odb” ‘<< Nome do banco de dados registrado’

oDBC = createUnoService( “com.sun.star.sdb.DatabaseContext” )
oBD = oDBC.getByName( sBancoDados )
oConexao = oBD.getConnection( “”,"" )
oDeclaracao = oConexao.createStatement()

sNome_Tabela = " ““TesteVar”” " ‘<< Nome da tabela’
sCampos = " "“var6"” "
Dia = DateSerial(2021,7,30)
Hora = TimeSerial(21,16,00)
sValores = Cdate(Dia + Hora)

sSQL = “INSERT INTO” & sNome_Tabela & “(” & sCampos & “) VALUES (” & “30/07/2021 21:16:00” & “)”
oDeclaracao.executeUpdate( sSQL )

e, houve da mesma forma uma resposta de erro a tentativa de entrada no BD:

Erro de execução do BASIC.
Ocorreu uma exceção
Type: com.sun.star.sdbc.SQLException
Message: firebird_sdbc error:
*Dynamic SQL Error
*SQL error code = -104
*Token unknown - line 1, column 55
*21
caused by
‘isc_dsql_prepare’

O básico é muito “flexível” com tipos de dados. Não deixe que o Basic determine o tipo de dados, sempre defina explicitamente o tipo de dados correto.

Para as instruções SQL “tudo deve ser texto”, mesmo que alguns valores sejam aceitos, pois faz uma conversão “on-the-fly”.

Se você anexar um exemplo de seu banco de dados, eu posso ajudá-lo com a declaração correta.

Elmau, meu banco de dados é novo, não possui registros. Consigo inserir, através de sql, valores de registros numéricos, assim como os de textos. Entretanto, quando vou para a inserção de campos que contenham data e hora a coisa complica, no que tange a data utilizo o DateSerial(2021,10,17) e consigo inserir normalmente no BD no campo do tipo (Double) a variável na macro possui o mesmo tipo. Entretanto, quando tento inserir a hora o BD retorna os erros que relatei. Fiz as seguintes tentativas sem sucesso:

  1. Inserir Data/Hora (timestamp)
    tentei agrupar a data e hora em uma variável do tipo timestamp com dateserial() + timeserial()

  2. Inserir Data + Hora
    tentei também inserir um campo dia (Double) e Hora (Double), o dia obtive sucesso, entretanto a hora o bd retornou erro.

  3. Data e Hora no formato texto
    Por final tentei transformar em texto: sValores = Cdate(Dia + Hora) e fazer a sql para armazenar o valor contido em sValores em um campo do BD do tipo VARCHAR. Mas ainda sem sucesso.

Poderia me ajudar realizando um teste em seu Libreoffice Base criando um único campo de tempo (H:M:S) e fazer um teste inserindo valores, caso obtenha sucesso e pudesse ampliar para um exemplo com variável do tipo timestamp ficaria perfeito.

Obrigado Elmau.

Mais uma vez, TODOS os dados devem ser passados como TEXTO, não tente mais nada.

Sub insertar_datos()
	DB_NAME = "test1"
	
	dbc = createUnoService( "com.sun.star.sdb.DatabaseContext" ) 
	db = dbc.getByName(DB_NAME) 
	conn = db.getConnection("", "")
	
	query = conn.createStatement()
	
	fecha = Format(Now(), "'YYYY-MM-DD'")
	hora = Format(Now(), "'HH:MM:SS'")
	fechahora = Format(Now(), "'YYYY-MM-DD HH:MM:SS'")
	
	sql = "INSERT INTO ""Table1"" (""date"", ""time"", ""datetime"") VALUES (" _
		+ fecha + ", "_
		+ hora + ", "_
		+ fechahora + _
		+ ")"
	query.executeUpdate(sql)
	
	sql = "INSERT INTO ""Table1"" (""date"", ""time"", ""datetime"") VALUES (" _
		+ fecha + ", "_
		+ hora + ", "_
		+ "CURRENT_TIMESTAMP" + _
		+ ")"
	query.executeUpdate(sql)
	
End Sub
2 Likes

Elmau, agradeço imensamente sua contribuição para a solução do problema . O problema estava justamente no detalhe que havia frisado: inserir no BD no formato de string utilizando o " ’ ’ " . Dessa forma consegui qualquer um dos tipos que precisava.
Fiz a alteração na linha com base em seu código:
TempoRegistro = Format( DateSerial(2021,10,17) + TimeSerial(21,16,00) , “‘YYYY-MM-DD HH:MM:SS’” )
Agredeço também ao colega Ohallot que fez contribuições .

1 Like