none
Criar Agendamento: Validação de horário RRS feed

  • Pergunta

  • Olá Pessoal,

     

    Estou com o seguinte problema:

     

    Tenho uma intranet, onde existe um recurso para agendar as salas disponíveis que tenho na empresa, o sistema funcionava normalmente, até descobrirmos um problema na validação dos horários solicitados, vou tentar explicar o que ocorre:

     

    Na página GerAgendamento.aspx tenho um formulário onde o usuário seleciona a sala e o horário desejado, para verificar se o horário está disponível, ao clicar no botão incluir(onde a lógica está na página GerAgendamento.aspx.vb), a validação é feita verificando se a hora inicial que existe no banco está entre a hora inicial e a hora final solicitada ou se a hora final que existe no banco está entre a hora inicial e a hora final solicitada. É aí que está problema, como a verificação é feita somente validando se a hora que existe no banco está entre a hora solicitada ao fazer um agendamento onde o horário solicitado está entre a hora que existe no banco o agendamento é concluído, fazendo com que existam dois agendamentos que irão acontecer na mesma sala e horário, por exemplo:

     

    Agendamento1 25/12/2008 18:00 às 22:00

    Agendamento2 25/12/2008 19:00 às 21:00

     

    Já tentei incluir mais uma condição para verificar se o horário solicitado está entre o horário existente no banco, mas não obtive sucesso.

     

    Ficaria muito agradecido se alguém pudesse me ajudar!

    segunda-feira, 10 de novembro de 2008 16:16

Respostas

  • Olá Pessoal,

    Depois de muitos testes eis a solução:

    *Onde era assim:

    mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner  
    join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND  
    ((a.hr_inicial BETWEEN '" & hinicial & "' AND '" & hfinal & "') or (a.hr_final BETWEEN '" &  
    hinicial & "' AND '" & hfinal & "'))", myConection) 
     
    *Ficou assim:
    mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner  
    join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND  
    (((a.hr_inicial > '" & hinicial & "' AND a.hr_inicial < '" & hfinal & "') or (a.hr_final > '"  
    & hinicial & "' AND a.hr_final < '" & hfinal & "') or ('" & hinicial & "' = a.hr_inicial and  
    '" & hfinal & "' = a.hr_final) or (a.hr_final = '" & hfinal & "' and '" & hinicial & "' >  
    a.hr_inicial) or (a.hr_inicial = '" & hinicial & "' and '" & hfinal & "' < a.hr_final)) or  
    (a.hr_inicial < '" & hinicial & "' AND a.hr_final > '" & hfinal & "'))", myConection) 



    Um artigo interessante (indicado pelo amigo Israel Aece) que me ajudou e pode ajudar pessoas que tiverem o mesmo problema é: http://www.sqlservercentral.com/articles/Advanced+Querying/3136/  (exige login).

    A lógica ficou um pouco complexa, mas funcionou!

    Até mais...
    • Marcado como Resposta brogliatto quinta-feira, 19 de março de 2009 14:48
    quinta-feira, 19 de março de 2009 14:43

Todas as Respostas

  • Olá Brogliatto,

     

    Seja bem vindo ao fórum de SQL Server no MSDN. Nós participantes do fórum tentaremos ajudá-lo na resolução de suas dúvidas e solução de seus problemas com SQL Server através de nossa experiência, disponibilidade e conhecimento.

     

    O problema que você está descrevendo chama-se Overlapping ou seja sobreposição. Há algumas formas de tratar o Overlapping mas nenhuma é tão trivial assim. No momento não possuo tanto tempo para postar uma situação com scripts detalhados (se alguém tiver poste-a), mas posso indicar que no livro Inside Sql Server T-SQL Programming você encontrará a resposta.

     

    Posso tentar retornar assim que tiver um tempinho caso você não possua o livro e ninguém tenha uma solução direta para ajudá-lo.

     

    [ ]s,

     

    Gustavo

    segunda-feira, 10 de novembro de 2008 17:04
  • Olá Gustavo,

    Obrigado pela indicação do livro, vou tentar encontrá-lo.

    Mas se você, ou o restante do pessoal do forum puderem me ajudar seria mais interessante, enquanto aguardo a ajuda tentarei encontrar o livro, se eu conseguir solucionar o problema compartilharei com vocês.

    Muito obrigado,
    Brogliatto
    segunda-feira, 10 de novembro de 2008 19:28
  • Brogliatto,

     

    Gostaria também de dar as boas vindas, seja bem vindo ao nosso fórum, esperamos poder ajudar de acordo com a nossa disponibilidade e conhecimento, faça parte desta grande comunidade, nos ajude a tornar este fórum uma grande fonte de conhecimento, contribua com suas dúvidas, informações, colabore com os demais participantes.

     

    Em relação a sua dúvida, realmente ela é um pouco fora da normalidade de dúvidas postadas aqui no fórum, ainda mais quando falamos de validação de horários ou melhor dizendo overlapping(sobreposição de valores).

     

    Com certeza este livro indicado pela Gustavo será um ótimo material, mas você poderia fornecer um pouco mais de detalhe sobre exatemente o que você deseja?

    terça-feira, 11 de novembro de 2008 10:16
  • Olá Junior,

    Obrigado pelo interesse em ajudar! Sei que pelo visto deve ser meio complexo a resolução deste problema, conversei com algumas pessoas que trabalham com BD e elas também ficaram um pouco confusas! Mas enfim tentarei explicar de uma maneira melhor, e colocando o código para que facilite o entendimento.

    Bom, o que eu preciso é verificar se o horário solicitado no agendamento está entre algum horário existente na tabela do banco e se algum horário existente no banco está entre o horário solicitado, caso essas condições sejam verdadeiras ele deverá mostrar a mensagem de que o horário está indisponível; isto é necessário para que o agendamento entre horários não aconteça, hoje por exemplo ao agendar uma sala das 18:00 às 22:00 consigo criar um agendamento dentro deste horário, por exemplo: das 20:00 às 21:00.

    É possível criar o agendamento entre o horário já agendado pelo motivo de as condições existentes no código fazerem a validação somente verficando se o horário que existe na tabela do banco está entre o horário solicitado, mas ele deveria verificar também se o horário solicitado está entre o horário existente na tabela do banco.

    Para facilitar o entendimento, segue o código executado ao clicar no botão Incluir Agendamento:

    Protected Sub Button3_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button3.Click
            Dim ds_altera As New Data.DataTable
            Dim hinicial As String
            Dim hfinal As String
            hinicial = Format(DateTime.Parse(TextBox6.Text.ToString), "yyyy-MM-dd") + " " + DropDownList7.SelectedValue + ":" + DropDownList8.SelectedValue + ":00.000"
            hfinal = Format(DateTime.Parse(TextBox6.Text.ToString), "yyyy-MM-dd") + " " + DropDownList9.SelectedValue + ":" + DropDownList10.SelectedValue + ":00.000"
            mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND ((a.hr_inicial BETWEEN '" & hinicial & "' AND '" & hfinal & "') or (a.hr_final BETWEEN '" & hinicial & "' AND '" & hfinal & "'))", myConection)
            mySQL.Fill(ds_altera)
            If ds_altera.Rows.Count <> 0 Then
                Label3.Visible = True
                GridView5.DataSource = ds_altera
                GridView5.DataBind()
            Else
                Dim comando As Data.SqlClient.SqlCommand = New Data.SqlClient.SqlCommand("INSERT INTO agsalasdigitais (usuario,sala,data,hr_inicial,hr_final,conteudo,auxilio_info,airliner,sympodium) VALUES ('" & User.Identity.Name & "','" & DropDownList6.SelectedValue & "','" & Format(DateTime.Parse(TextBox6.Text.ToString), "yyyy-MM-dd") & "','" & hinicial & "','" & hfinal & "','" & TextBox7.Text & "','" & Convert.ToInt16(CheckBox4.Checked) & "','" & Convert.ToInt16(CheckBox5.Checked) & "','" & Convert.ToInt16(CheckBox6.Checked) & "')", myConection)
                myConection.Open()
                comando.ExecuteNonQuery()
                myConection.Close()
                Panel2.Visible = False
                TextBox6.Text = ""
                TextBox7.Text = ""
                DropDownList6.SelectedValue = "Auditório"
                DropDownList7.SelectedValue = "07"
                DropDownList8.SelectedValue = "00"
                DropDownList9.SelectedValue = "07"
                DropDownList10.SelectedValue = "00"
                CheckBox4.Checked = False
                CheckBox5.Checked = False
                CheckBox6.Checked = False
                sqlSalasDigitais.DataBind()
                GridView3.DataBind()
            End If
        End Sub

    Observe que as condições da cláusula Where estão verificando se o valor existente no campo (
    a.hr_inicial) do bd estão entre o horário solicitado (hinicial e hfinal), é feito a mesma verificação com o campo a.hr_final.

    Tentei fazer algumas mudanças nas condições, para que fosse verificado se os horários solicitados estão entre os campos do bd deixando-as da seguinte maneira:

     mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND ((a.hr_inicial BETWEEN '" & hinicial & "' AND '" & hfinal & "') AND('" & hinicial & "' BETWEEN a.hr_inicial AND a.hr_final) or (a.hr_final BETWEEN '" & hinicial & "' AND '" & hfinal & "') AND ('" & hfinal & "' BETWEEN a.hr_inicial AND a.hr_final))", myConection)


    Mas desta forma o problema piorou, assim eu consigo tanto agendar um horário que esteja dentro de um horário existente, quanto agendar um horário que englobe o horário existente.



    Mais uma vez muito obrigado pela ajuda e cooperação de todos!
    Brogliatto
    terça-feira, 11 de novembro de 2008 12:00
  • E aí pessoal???

    Alguém chegou a tentar alguma coisa em relação ao problema acima?

    Abraços,
    Brogliatto
    quinta-feira, 13 de novembro de 2008 10:56
  • Olá Pessoal,

    Depois de muitos testes eis a solução:

    *Onde era assim:

    mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner  
    join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND  
    ((a.hr_inicial BETWEEN '" & hinicial & "' AND '" & hfinal & "') or (a.hr_final BETWEEN '" &  
    hinicial & "' AND '" & hfinal & "'))", myConection) 
     
    *Ficou assim:
    mySQL = New Data.SqlClient.SqlDataAdapter("select a.*, u.nome from agsalasdigitais a inner  
    join usuarios u on a.usuario=u.usuario where a.sala='" & DropDownList6.SelectedValue & "' AND  
    (((a.hr_inicial > '" & hinicial & "' AND a.hr_inicial < '" & hfinal & "') or (a.hr_final > '"  
    & hinicial & "' AND a.hr_final < '" & hfinal & "') or ('" & hinicial & "' = a.hr_inicial and  
    '" & hfinal & "' = a.hr_final) or (a.hr_final = '" & hfinal & "' and '" & hinicial & "' >  
    a.hr_inicial) or (a.hr_inicial = '" & hinicial & "' and '" & hfinal & "' < a.hr_final)) or  
    (a.hr_inicial < '" & hinicial & "' AND a.hr_final > '" & hfinal & "'))", myConection) 



    Um artigo interessante (indicado pelo amigo Israel Aece) que me ajudou e pode ajudar pessoas que tiverem o mesmo problema é: http://www.sqlservercentral.com/articles/Advanced+Querying/3136/  (exige login).

    A lógica ficou um pouco complexa, mas funcionou!

    Até mais...
    • Marcado como Resposta brogliatto quinta-feira, 19 de março de 2009 14:48
    quinta-feira, 19 de março de 2009 14:43