Jump to content
paulordl

Projeto de Curso com SQL

Recommended Posts

paulordl

Boas,

Tenho quase finalizado o meu projeto de curso, mas tenho verificado que me tem dado um erro, ou seja se criar um paciente com o mesmo nome mas com chaves primarias diferentes, eu quando o vou escolher aparece o dois mas quando mostra os dados só mostra de um...

Quer escolha o nome de cima ou de baixo nunca muda os dados das textbox...

Segue um exemplo, com o codigo da combobox que preenche os dados das textbox.

62b26b6d8d13fe874183395d5aee5f9c.png

Try
	    novo = False
	    Call ApagarFormulário()
	    If con_bd.State = ConnectionState.Open Then con_bd.Close()
	    con_bd.Open()
	    Dim cmd As New OleDbCommand("select * from Pacientes WHERE NomePac = '" & cbpaciente.SelectedItem & "'", con_bd)
	    Dim drdr As OleDbDataReader
	    drdr = cmd.ExecuteReader
	    drdr.Read()
	    txtnome.Text = drdr.Item("NomePac")
	    dtdata.Value = drdr.Item("idade")
	    txtcontribuinte.Text = drdr.Item("Contribuinte")
	    txtmorada.Text = drdr.Item("Morada")
	    txtcontacto.Text = drdr.Item("Telemovel")
	    txtbi.Text = drdr.Item("BI")
	    txtcodpac.Text = drdr.Item("CodPac")
	    txtnrutente.Text = drdr.Item("NumeroUtente")
	    cmd.Cancel()
	    con_bd.Close()
	    btoeditar.Visible = True
	    btoapagar.Visible = True
	    EliminarToolStripMenuItem.Visible = True
	    EditarToolStripMenuItem.Visible = True
    Catch ex As Exception
	    MsgBox(ex.Message)
    End Try

Share this post


Link to post
Share on other sites
FreiNando

O resultado não podia ser diferente, porque a pesquisa é a mesma.

Na realidade a pesquisa devolve dois registos, só que você apenas mostra os dados do primeiro. Para mostrar o segundo registo teria que fazer mais um drdr.Read. Vamos a ver é como podíamos saber se o item escolhido é o primeiro ou o segundo... e se housesse três? ou quatro?

A solução passa por criar uma lista de pacientes sem repetição de valores, quer adicionando mais algum dado, ou simplesmente criar uma lista paralela à existente com os valores do campo com a chave primária.

Ou então criar um objecto que indique quantos registos a pesquisa devolveu e, adicionar uma espécie de navegador nesses registos, tipo setas a mostrar que existe outros registos... claro que seria muito mais trabalhoso...


O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites
paulordl

Como seria então o segundo drdr.read ?

Queria pelo menos ter dois registos iguais só para disfarçar pelo menos...

Share this post


Link to post
Share on other sites
FreiNando

Cada OleDbDataReader.Read() lê um registo da pesquisa à base de dados. Ao fazeres um Read obtens o primeiro registo, caso haja outro registo tens de fazer outro Read para o poderes ler. Se não houver outro registo, fazer um novo read irá dar erro.

Para evitar isso deves usar outra forma de ler os registos, que é mais apropriada para ler uma quantidade de registos indeterminada:

While drdr.Read()
 'Ler os campos
End While


O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites
paulordl

Try
	    novo = False
	    Call ApagarFormulário()
	    If con_bd.State = ConnectionState.Open Then con_bd.Close()
	    con_bd.Open()
	    Dim cmd As New OleDbCommand("select * from Cirurgia, Tipos, Pacientes, Medicos, Equipa WHERE Cirurgia.CodPac=Pacientes.CodPac and Cirurgia.CodTipo=Tipos.CodTipo and Cirurgia.CodEqui=Equipa.CodEqui and Cirurgia.CodMed=Medicos.CodMed and NomePac = '" & cbnomepac1.SelectedItem & "' ", con_bd)
	    Dim drdr As OleDbDataReader
	    drdr = cmd.ExecuteReader
	    While drdr.Read()
		    'Ler os campos
		    txtcodcir.Text = drdr.Item("CodCir")
		    cbpacientes.SelectedItem = drdr.Item("NomePac")
		    cbtipos.SelectedItem = drdr.Item("Tipo")
		    cbequipa.SelectedItem = drdr.Item("Descricao")
		    cbmedicos.SelectedItem = drdr.Item("NomeMed")
		    dtdata.Value = drdr.Item("Data")
		    txtutente.Text = drdr.Item("NumeroUtente")
		    txtcontribuinte.Text = drdr.Item("Contribuinte")
		    cmd.Cancel()
		    con_bd.Close()
		    btoimprimir.Visible = True
		    btoeditar.Visible = True
		    btoapagar.Visible = True
		    EditarToolStripMenuItem.Visible = True
		    EliminarToolStripMenuItem.Visible = True
	    End While

    Catch ex As Exception
	    MsgBox(ex.Message)
    End Try

Está-me a dar erro :/

Share this post


Link to post
Share on other sites
FreiNando

Claro!!

Estás a fechar a conexão antes de terminar a leituras dos dados.

As instruções começando com cmd.Cancel até End While (não incluido) deves passar para fora do ciclo.

Não é preciso abrir e fechar constantemente a conexão, e no inicio deves verificar se a mesma está fechada, para a abrir, e não o inverso. Fechar para voltar a abrir imediatamente a seguir é uma perda de tempo.

Também deves fechar o DataReader depois de terminadas as leituras e antes de fechar a Conexão.

E para evitar outros erros indesejados o Try ... Catch não deve conter a abertura e fecho de conexões ou DataReaders, não vá um erro deixá-las abertas...

Edited by FreiNando

O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites
paulordl

 Try
	    novo = False
	    Call ApagarFormulário()
	    If con_bd.State = ConnectionState.Open Then con_bd.Close()
	    con_bd.Open()
	    Dim cmd As New OleDbCommand("select * from Pacientes WHERE NomePac = '" & cbpaciente.SelectedItem & "'", con_bd)
	    Dim drdr As OleDbDataReader
	    drdr = cmd.ExecuteReader
	    While drdr.Read()
		    txtnome.Text = drdr.Item("NomePac")
		    dtdata.Value = drdr.Item("idade")
		    txtcontribuinte.Text = drdr.Item("Contribuinte")
		    txtmorada.Text = drdr.Item("Morada")
		    txtcontacto.Text = drdr.Item("Telemovel")
		    txtbi.Text = drdr.Item("BI")
		    txtcodpac.Text = drdr.Item("CodPac")
		    txtnrutente.Text = drdr.Item("NumeroUtente")
		    drdr.Close()
	    End While
	    cmd.Cancel()
	    con_bd.Close()
	    btoeditar.Visible = True
	    btoapagar.Visible = True
	    EliminarToolStripMenuItem.Visible = True
	    EditarToolStripMenuItem.Visible = True

    Catch ex As Exception
	    MsgBox(ex.Message)
    End Try

Tentei assim mas dá-me a mesma erro :/ consegues por-me o codigo sem erro?

tenho de entregar segunda e só me falta mesmo isto :/

Share this post


Link to post
Share on other sites
FreiNando

O drdr.Close deve acontecer depois da leituras dos dados, ou seja fora do ciclo While.

Penso que a mensagem de erro deve indicar isso...

Obs.: Try... Catch (tratamento de erros) deve ser evitado ao máximo no acesso a base de dados (usando OleDb), por causa das conexões que podem ficar abertas. Até porque o programa não crasha em caso de erro, sendo informado o utilizador da ocorrência do erro e a indicação se quer continuar ou não. E até mostra em que modulo e linha esse erro ocorreu (configuração da compilação por defeito).


O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites
paulordl

Com código da forma que me foi dito, não faz nada ou seja com o while

Try
	    novo = False
	    Call ApagarFormulário()
	    If con_bd.State = ConnectionState.Open Then con_bd.Close()
	    con_bd.Open()
	    Dim cmd As New OleDbCommand("select * from Pacientes WHERE NomePac = '" & cbpaciente.SelectedItem & "'", con_bd)
	    Dim drdr As OleDbDataReader
	    drdr = cmd.ExecuteReader
	    While drdr.Read()
		    txtnome.Text = drdr.Item("NomePac")
		    dtdata.Value = drdr.Item("idade")
		    txtcontribuinte.Text = drdr.Item("Contribuinte")
		    txtmorada.Text = drdr.Item("Morada")
		    txtcontacto.Text = drdr.Item("Telemovel")
		    txtbi.Text = drdr.Item("BI")
		    txtcodpac.Text = drdr.Item("CodPac")
		    txtnrutente.Text = drdr.Item("NumeroUtente")
	    End While
	    drdr.Close()
	    cmd.Cancel()
	    con_bd.Close()
	    btoeditar.Visible = True
	    btoapagar.Visible = True
	    EliminarToolStripMenuItem.Visible = True
	    EditarToolStripMenuItem.Visible = True
    Catch ex As Exception
	    MsgBox(ex.Message)
    End Try

d68dd54e9808779cd615bee3e7fe3fae.png

Share this post


Link to post
Share on other sites
FreiNando

Retira o TRY e faz DEBUG!

Não há melhor forma de verificares onde está o erro!


O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites
paulordl

 novo = False
 Call ApagarFormulário()
 If con_bd.State = ConnectionState.Open Then con_bd.Close()
 con_bd.Open()
 Dim cmd As New OleDbCommand("select * from Pacientes WHERE NomePac = '" & cbpaciente.SelectedItem & "'", con_bd)
 Dim drdr As OleDbDataReader
 drdr = cmd.ExecuteReader
 While drdr.Read()
	 txtnome.Text = drdr.Item("NomePac")
	 dtdata.Value = drdr.Item("idade")
	 txtcontribuinte.Text = drdr.Item("Contribuinte")
	 txtmorada.Text = drdr.Item("Morada")
	 txtcontacto.Text = drdr.Item("Telemovel")
	 txtbi.Text = drdr.Item("BI")
	 txtcodpac.Text = drdr.Item("CodPac")
	 txtnrutente.Text = drdr.Item("NumeroUtente")
 End While
 drdr.Close()
 cmd.Cancel()
 con_bd.Close()
 btoeditar.Visible = True
 btoapagar.Visible = True
 EliminarToolStripMenuItem.Visible = True
 EditarToolStripMenuItem.Visible = True

Já retirei e nada :/ não dá erro nenhum mas apenas mostra os dados de um dos pacientes

Está aqui o Link do programa, a apresentação é sexta e o unico problema que me está a dar dores de cabeça é este :/

Acha que me consegue ajudar? Agredeço-lhe imenso a si ou quem me conseguir ajudar, obrigado

User: Admin

Pass: pass

https://goo.gl/k043N9

Edited by paulordl

Share this post


Link to post
Share on other sites
FreiNando

Vamos por partes...

O erro que dizes acontecer é não mostrar os dois registos?

Isso não é erro, e a falha está na sequência de acontecimentos.

E onde pensas que deveria mostrar os valores do segundo registo se apenas tens local para mostrar um registo?

No teu caso está a substituir os do primeiro registo.

Por isso, para atingires teu objectivo, tens criar uma espécie de navegador de registos, digamos por exemplo um botão para navegar para o registo seguinte e outro para o registo anterior. Esses botões seriam activados, caso existisse mais de um registo e juntamente com uma variável a indicar o número de ordem do registo actual, de preferência a começar em 0. (Observa as tabelas do Access com o navegador)

Edited by FreiNando

O caminho mais curto para conseguir fazer muitas coisas é fazer uma de cada vez. Samuel Smiles

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.