E ae pessoal!
Mais uma vez venho eu recorrer a vocês!
É o 'sisguinte', na minha aplicação em vb.net eu pego de um banco de dados sql local e escrevo em um outro local (reformatando os campos) e em um outro remoto.
O motivo da escrita no remoto e no local (reformatado) é diferente.
No bd local original eu tenho duas colunas booleanas - EnviadoPI e EnviadoLocalMES - que me dizem se o dado já foi enviado alguma vez para algum dos outros bancos.
O problema é:
1 - Quando o dado nasce, ele não é necessariamente enviado.
2 - na hora de enviar:
2.1- Primeiro vai para o PI e atualiza sua coluna EnviadoPI (banco remoto)
2.2 - Depois vai pro LocalMES e atualiza sua coluna EnviadoLocalMES
- caso dê erro no envio ele loga o erro e aborta as rotinas, ou seja, deixa de enviar o restante.
Com isso, não é necessariamente verdade que eu tenha que enviar sempre para o LocalMES e o PI junto.
Porém, da maneira como criei meu programa, ele lê o banco de dados original e faz:comandoSelectSQLDadosDesenfornamento.CommandText = _
"SELECT " & _
"DateAndTime as DataHora, TagIndex as id, Val as Valor, EnviadoPI, EnviadoLocalMES " & _
"FROM " & _
"FloatTable " & _
"WHERE " & _
"(DateAndTime IS NOT NULL) AND " & _
"(TagIndex IS NOT NULL) AND " & _
"(Val IS NOT NULL) AND" & _
"(((EnviadoPI != 'False') OR (EnviadoPI IS NULL)) OR" & _
"((EnviadoLocalMES != 'False') OR (EnviadoLocalMES IS NULL)))" & _
"ORDER BY " & _
"DateAndTime"
Ou seja, ele pega todo mundo que não tenho sido enviado para o PI OU que não tenha sido enviado para o LocalMES e armazena num dataset.
Na hora de escrever nos bancos, obviamente ele escreve um de cada vez e atualiza a respectiva coluna no dataset.
If dsDadosBat4e5.Tables("DadosDesenfornamento").Rows.Count > 0 Then
'Loop para gravar os dados de Desenfornamento no PI.
For Each linhaAuxiliarDesenfornamento In dsDadosBat4e5.Tables("DadosDesenfornamento").Rows
If (IsDBNull(linhaAuxiliarDesenfornamento.Item("EnviadoPI")) Or linhaAuxiliarDesenfornamento.Item("EnviadoPI").Equals(False)) Then
'Faz o tratamento dos ids, para ser escrito no PI.
'O Tag Bat4e5_RtPM_Desenforn_Maquina identifica a Desenfornadora (3, 4 ou 5)
Select Case linhaAuxiliarDesenfornamento.Item("id")
Case 0
Tag1 = "Bat4e5_RtPM_Desenforn_AmperagemMax"
Case 1
Tag1 = "Bat4e5_RtPM_Desenforn_AmperagemMedia"
Case 2
Tag1 = "Bat4e5_RtPM_Desenforn_Numforno"
Case 3
Tag1 = "Bat4e5_RtPM_Desenforn_Maquina"
Case 4
Tag1 = "Bat4e5_RtPM_Desenforn_TempoCoqueif"
'DataHora Real, Programada, Temperatura1, 2 e 3 ainda não implementadas
Case 5
Tag1 = "Bat4e5_RtPM_Desenforn_DataHora_Programada"
Case 6
Tag1 = "Bat4e5_RtPM_Desenforn_DataHora_Real"
Case 7
Tag1 = "Bat4e5_RtPM_Desenforn_Temperatura1"
Case 8
Tag1 = "Bat4e5_RtPM_Desenforn_Temperatura2"
Case 9
Tag1 = "Bat4e5_RtPM_Desenforn_Temperatura3"
End Select
comandoInsertPIDadosBat4e5.CommandType = CommandType.Text
comandoInsertPIDadosBat4e5.CommandText = _
"INSERT INTO " & _
"picomp2 " & _
"(tag, time, value) " & _
"VALUES " & _
"('" & Tag1 & "', " & _
"'" & Format(CDate(linhaAuxiliarDesenfornamento.Item("DataHora")), "dd/MM/yyyy HH:mm:ss") & "', " & _
"'" & Trim(linhaAuxiliarDesenfornamento.Item("Valor")).ToString & "')"
comandoInsertPIDadosBat4e5.Connection = conexaoPIDadosBat4e5
adaptadorPIDadosBat4e5.InsertCommand = comandoInsertPIDadosBat4e5
Try
conexaoPIDadosBat4e5.Open()
adaptadorPIDadosBat4e5.InsertCommand.ExecuteReader()
Catch ex As Exception
MessageBox.Show(ex.ToString)
arqLog.EscreverLinha(Format(Now, "yyyy-MM-dd HH:mm:ss") & " " & "Erro: Falha na gravação do tag dados de Desenfornamento " & linhaAuxiliarDesenfornamento.Item("id") & " - " & ex.Message)
erroGravacaoPI = True
Exit For
Finally
If conexaoPIDadosBat4e5.State <> ConnectionState.Closed Then
conexaoPIDadosBat4e5.Close()
End If
End Try
End If
'Atualizando o flag de 'EnviadoPI' na tabela de Desenfornamento do RS View do banco local.
If Not erroGravacaoPI Then
comandoUpdateSQLDadosDesenfornamento.CommandType = CommandType.Text
comandoUpdateSQLDadosDesenfornamento.CommandText = _
"UPDATE " & _
"FloatTable " & _
"SET " & _
"EnviadoPI = 'True' " & _
"WHERE " & _
"(DateAndTime = " & "CONVERT(DATETIME, '" & Format(CDate(linhaAuxiliarDesenfornamento.Item("DataHora")), "yyyy-MM-dd HH:mm:ss") & "', 102)" & ") AND " & _
"(Val = '" & linhaAuxiliarDesenfornamento.Item("Valor") & "'" & ")"
comandoUpdateSQLDadosDesenfornamento.Connection = SqlConexaoDadosDesenfornamento
adaptadorSQLDadosDesenfornamento.UpdateCommand = comandoUpdateSQLDadosDesenfornamento
Try
SqlConexaoDadosDesenfornamento.Open()
adaptadorSQLDadosDesenfornamento.UpdateCommand.ExecuteReader()
Catch ex As Exception
MessageBox.Show(ex.ToString)
arqLog.EscreverLinha(Format(Now, "yyyy-MM-dd HH:mm:ss") & " " & "Erro: Falha na atualização do flag 'EnviadoPI' na tabela de Desenfornamento do banco de dados do RS View!" & " - " & ex.Message)
erroGravacaoPI = True
Exit For
Finally
If SqlConexaoDadosDesenfornamento.State <> ConnectionState.Closed Then
SqlConexaoDadosDesenfornamento.Close()
End If
End Try
End If
Para cada linha no dataset ele faz isso.
O problema é que na hora de fazer a mesma coisa para o MES eu vou ter que abrir uma conexão nova com o banco sql.
A minha pergunta é:
O certo seria atualizar o banco de dados 1 vez só no final da rotina (pensando em eficiência) porém como eu falei, se der um erro, perco as atualizações que deveriam ter sido feitas até aquele momento e corro o risco de re-enviar dados desnecessariamente.
Logo eu perco eficiência praticamente dobrando meus acessos ao banco de dados.
Alguém tem alguma idéia mágica para me ajudar?
A máquina que isso vai rodar é boa porém ela tem duzentas outras aplicações mais imoportantes rodando 'full-time' enquanto essa rotina é lançada de tempos em tempos quando ocorre um evento pré-determinado, logo, não quero destruir o processamento dela com enormes loops duplicados e triplicados à toa...
Vocês pelo menos entenderam a idéia? :roll: Eu imagino que ela esteja meio confusa, vou tentar pensar numa maneira de explicar melhor e posto aqui.
Abração!
edit 1:
Já pensei um pouco.
Nesse caso, essas coisas seriam pesadas, as conexões, leituras, escritas no banco de dados, dataset, o tratamento dos dados (formatação de strings por exemplo)?
Eu nunca fiz nada 'concreto' (se podemos dizer) em sql e vb.net para ter essas informações.
Esse que é o meu dilema, abusar da segurança lendo e escrevendo separadamente, abrindo mão assim da eficiência, ou tentar otimizar algumas coisas.
Lembrando que pelo que eu vi no histórico desse processo, o evento de envio acontece umas 10x por dia e são normalmente uns 40-50 dados por envio.
Ah, outra coisa!
São 3 conjuntos de tabelas originais (ou 3 BD diferentes) que passam pelas mesmas rotinas ao mesmo tempo, mesmo que apenas um tenha sido atualizado com dados novos.