Jump to content


Photo

Problema Com Funções


  • Faça o login para participar
5 replies to this topic

#1 cacfs

cacfs

    Turista

  • Usuários
  • 50 posts
  • Sexo:Não informado

Posted 04/04/2005, 11:24

Venho pedir ajuda novamente.

Quando tento fazer uma função, que acessa o banco de dados, e no final dessa funcção ela chama uma outra função que també m acessa o banco de dados, dá erro dizendo que a conexão já está aberta, ou que já existe um data reader para essa conexao. Me ajudem por favor, segue o código:

'carrega as respostas com o resultado
    Public Sub carrega_resultado(ByVal intCodPerg As Integer)
        Dim strRespostas As String
        Dim cmdRespostas As OleDbCommand
        Dim intResultPerg As Integer
        'recupera o total de vezes que a pergunta foi respondida
        intResultPerg = resultado_pergunta(Convert.ToInt32(cbPerguntas.SelectedValue))
        Try
            'abre conexao
            objConnP.Open()
            'monta o SELECT para recuperar as respostas
            strRespostas = "SELECT r.cod_resposta, " & _
                           "r.desc_resposta " & _
                           "FROM respostas AS r " & _
                           "WHERE r.cod_pergunta = " & intCodPerg
            cmdRespostas = New OleDbCommand(strRespostas, objConnP)
            'executa o comando e preenche o datareader das respostas
            drRespostas = cmdRespostas.ExecuteReader
        Catch erro As Exception
            MsgBox("Erro (039): " & erro.Message, MsgBoxStyle.Critical)
        
        End Try
        'criando objetos para criar o resultado
        Dim dtResultado As New DataTable("Resultado")
        Dim dtcResultado As DataColumn
        Dim dtrResultado As DataRow
        'criando as colunas da tabela
        'codigo resposta
        dtcResultado = New DataColumn()
        dtcResultado.DataType = Type.GetType("System.Int32")
        dtcResultado.ColumnName = "Codigo"
        dtcResultado.ReadOnly = True
        dtcResultado.Unique = True
        dtResultado.Columns.Add(dtcResultado)
        'resposta
        dtcResultado = New DataColumn()
        dtcResultado.DataType = Type.GetType("System.String")
        dtcResultado.ColumnName = "Resposta"
        dtcResultado.ReadOnly = False
        dtcResultado.Unique = False
        dtResultado.Columns.Add(dtcResultado)
        'resultado
        dtcResultado = New DataColumn()
        dtcResultado.DataType = Type.GetType("System.Int32")
        dtcResultado.ColumnName = "Resultado"
        dtcResultado.ReadOnly = False
        dtcResultado.Unique = False
        dtResultado.Columns.Add(dtcResultado)
        Try
            'enquanto tiverem respostas
            While drRespostas.Read
                dtrResultado = dtResultado.NewRow
                dtrResultado("Codigo") = drRespostas.GetInt32(0)
                dtrResultado("Resposta") = drRespostas.GetString(1)
                dtrResultado("Resultado") = Convert.ToBoolean(resultado_resposta(drRespostas.GetInt32(0)) / intResultPerg)
                dtResultado.Rows.Add(dtrResultado)
            End While
            'preenche o datagrid
            dgResultado.DataSource = dtResultado
        Catch erro As Exception
            MsgBox("Erro (040): " & erro.Message, MsgBoxStyle.Critical)
        Finally
            'fecha conexao
            objConnP.Close()
        End Try
    End Sub

'retorna o numero de vezes que uma resposta foi citada
    Public Function resultado_resposta(ByVal intCodResp As Integer) As Integer
        Dim strResultado As String
        Dim cmdResultado As OleDbCommand
        Dim drResultado As OleDbDataReader
        Try
            'abre conexao
            objConnP.Open()
            'monta SELECT para contar os resultados das respostas
            strResultado = "SELECT COUNT(rp.cod_resposta_pergunta) AS totalResp " & _
                           "FROM  resposta_pergunta AS rp " & _
                           "WHERE rp.cod_resposta = " & intCodResp
            cmdResultado = New OleDbCommand(strResultado, objConnP)
            'executa o comando e preenche o datareader
            drresultado = cmdResultado.ExecuteReader
            'se tiver dados
            If drResultado.Read Then
                'retorna a quantidade de vezes que uma resposta foi citada
                Return drResultado.GetInt32(0)
            End If
        Catch erro As Exception
            MsgBox("Erro (042): " & erro.Message, MsgBoxStyle.Critical)
        Finally
            'fecha conexao
            objConnP.Close()
        End Try
    End Function


#2 viniciusjau

viniciusjau

    Veterano

  • Usuários
  • 1492 posts
  • Sexo:Masculino
  • Localidade:Jaú
  • Interesses:Web Designer em Geral

Posted 07/04/2005, 10:41

não li se codigo, mais você fechou a primeira conexão ??

#3 MACUL

MACUL

    Doutor

  • Usuários
  • 770 posts
  • Sexo:Masculino
  • Localidade:SP

Posted 07/04/2005, 11:28

na função resultado_resposta
tente trocar os nomes

objConnP
cmdResultado

para

objConnP2
cmdResultado2


T +
*************** M ** A ** C ** U ** L ***************

*************************************************

#4 cacfs

cacfs

    Turista

  • Usuários
  • 50 posts
  • Sexo:Não informado

Posted 14/04/2005, 15:04

Não deu certo, continua dizendo que a conexão já está aberta. Tentei não abrir a conexao na função resultado_resposta, ai ele diz que já tem um DataReader aberto para a conexao.

Acho que tenho que preencher todo o DataTable com os dados, deixando a coluna Resultado em branco, e depois percorrer todo DataTable, lendo a primeira coluna que é o código executando a função e gravando o retorno na coluna resultado do DataTable, o problema é que não sei como ler o dataTable, alguem poderia me ajudar?

#5 felipecm

felipecm

    Expert

  • Usuários
  • 541 posts
  • Sexo:Não informado
  • Localidade:ABC / SP

Posted 07/05/2005, 10:26

Não deu certo, continua dizendo que a conexão já está aberta. Tentei não abrir a conexao na função resultado_resposta, ai ele diz que já tem um DataReader aberto para a conexao.

Acho que tenho que preencher todo o DataTable com os dados, deixando a coluna Resultado em branco, e depois percorrer todo DataTable, lendo a primeira coluna que é o código executando a função e gravando o retorno na coluna resultado do DataTable, o problema é que não sei como ler o dataTable, alguem poderia me ajudar?

Bom.. vamos lá...

Velhinho, vc está tentando abrir a mesma conexao pelo metodo (resultado_resposta) sendo que ela já está aberta.

Outra prática que poderia ser feita nesse seu caso.
Na sub, ao invés de trabalhar com Reader, vc poderia fazer um Adapter e preencher um DataSet com a tua DataTable (seria bem mais facil e nao precisaria estar montando a estrutura da DataTable). O DataSet vc poderia usar como DataSource no Grid .. como o DataSet é uma Collection de DataTables, ou vc informa a DataTable do DataSet, ou então é selecionada a DataTable DefaultView do DataSet.

Outra coisa, no caso abaixo, vc também tem uma alternativa mais eficiente, o uso do método ExecuteScalar() de IDBCommand que retorna um unico valor de forma mais rapida e mais facil, pois vc retorna apenas o total (Count).

Ainda sim dando uma olhada por cima percebi que vc pode resolver todo o problema com apenas uma Sub, e tudo na mesma SQL:

SELECT r.cod_resposta, r.desc_resposta, Count(rp.cod_resposta_pergunta) AS Total FROM respost<span style='color:green'>as r LEFT OUTER JOIN resposta_pergunta rp ON r.cod_resposta = rp.cod_resposta WHERE r.cod_pergunta = " & intCodPerg & " GROUP BY r.cod_resposta, r.desc_resposta

Para trabalhar com DataTables....loope com For

For each tbRow in DataTable.Rows
  tbRow.Cells("nome da coluna").Text 
Next

For i = 0 to DataTable.Rows.Count -1
  DataTable.Rows(i).Cells("nome da coluna").Text 
Next


MCAD, MCP

#6 otavio

otavio

    http://www.cursosvirtuais.net

  • Usuários
  • 443 posts
  • Sexo:Não informado

Posted 18/05/2005, 03:55

fala brother...
como o DataReader um cursor somente "pra frente" ele nao pode voltar ou executar varias conexoes simultaneas,
como o desenpenho do DataSet é ridiculo comparado ao DataReader em aplicacoes web, se vc prescisa de desempenho e acesso a dados mto rapido sempre usa o DataReader...

pra usar varios datareaders dentro de um loop eh simples.. crie uma conexao pra cada um, pode parecer meio estranho criar varias conexoes...mas o conceito do ado.net é diferente do ado. somente abra as conexoes ao banco dentro de sua sub ou function especificas, evitando abrir uma conexao na sub onload.

pra contagem de registros vc tem q setar uma variavel do tipo Integer e NAO string como vc tava setando. olha o exemplo:

Dim count As Integer = CType(cmdsql.ExecuteScalar("SELECT count(id) FROM  tabela;", CommandType.Text), Integer)

o exemplo acima usa a classe DalHelper, ela facilita mto a vida de quem acessa dados com DataReader ou DataSet. pra ler mais sobre ela acessa: http://forum.wmonlin...&f=123&t=117621

[]'s
/////////////////////////////////////////////

http://www.cursosvirtuais.net/




1 user(s) are reading this topic

0 membro(s), 1 visitante(s) e 0 membros anônimo(s)

IPB Skin By Virteq