Solucionado (ver solução)
Solucionado
(ver solução)
9
respostas

Como inserir os valores de um select no banco de dados?

Boa noite, pessoal! Tenho o seguinte problema:

Tenho uma lista de pacientes, onde todos eles devem informar o seu peso e sua altura para que assim seja calculado o seu IMC, após as respostas, é apresentada uma tabela com tais informações. Porém quando um paciente não responde ao questionário (seja por atraso ou por falta em uma consulta) na tabela (onde mostro os dados para um relatório) abre um select para informar o que houve com determinado paciente, e com isso salvar a justificativa no banco de dados, a questão é que não estou conseguindo associar o select com o paciente que não respondeu o questionário, quando salvo a justificativa uma nova linha dentro da tabela do banco de dados é criada com todos os dados (nome, peso altura) null e aparece o IMC com o value do select.

E realizo tal procedimento com mais de um paciente ele salva somente uma das justificativas e a outra simplesmente ele ignora.

Segue o código:

<?php include("conexao.php");?>

<?php
    if(!empty($_POST["save_record"])) {
        require_once("conexao.php"); 
        $sql = "INSERT INTO pacientes (imc) VALUES (:imc)";
        $pdo_statement = $conexao->prepare( $sql );

        $result = $pdo_statement->execute( array( ':imc'=>$_POST['imc'] ));
    if (!empty($result) ){
        header('location:relatorio.php');
        }
    }
?>

<html>
<head>
    <meta charset="utf-8">
</head>
<body>

<?php    
    $pdo_statement = $conexao->prepare("SELECT * FROM pacientes left join clinica on pacientes.idpaciente = clinica.nomepaciente;");
    $pdo_statement->execute();
    $result = $pdo_statement->fetchAll();
?>

<form name="myform" action="" method="POST">          
    <div class="table-responsive">
    <table class="table table-striped table-bordered">
        <thead>
          <tr>
            <th> Data </th>
            <th> Nome </th>
            <th> Peso (kg) </th>
            <th> Altura </th>
        </thead>

        <tbody>

            <?php
               if(!empty($result)) :
               foreach($result as $row) :
           ?>

          <tr>
            <td> <?php echo $row["data"];?> </td>
             <td> <?php echo $row["nome"];?> </td>
            <td> <?php echo $row["peso"];?> kg  </td>
               <td> <?php echo $row["altura"]; ?> m  </td>
            <td> <?php echo $row["imc"];  
                     if($row["peso"] == ' ' ){ 
                        echo "<select name='status' style='width: 125px; height: 35px;'>";
                        echo "<option value='' selected disabled>  Justificativa   </option>";
                        echo "<option value='Atrasado'>   Atrasado   </option>";
                        echo "<option value='Falta'> Dispensado </option>";
                        echo "</select>";
          </tr>

        <?php
          endforeach    
        ?>

        <?php
        endif

        ?>
        </tbody>
     </table>
</div>

    <div>
        <input type="submit" name="save_record" id="btnSubmit1" class="btn btn-primary" value="Salvar">
        <input type="submit" id="cancelar" class="btn btn-danger value="Corrigir" onclick="javascript:corrigir();">
    </div>
</form> 
</body>
</html>

Como faço para corrigir tal bug e com isso associar o select com a linha do paciente que não respondeu ao questionário?

9 respostas

Oi João, tudo bem? Vamos por pasos.

1 - Você não pode criar um form só para a tabela inteira, por que se não, qual dado você tem certeza que tá capturando? Esse form vai estar associado a todos os pacientes, e não para um só.

2 - Os dados são inseridos novamente por que você tá usando a instrução INSERT, e não UPDATE que é pra atualizar o registro.

3 - Você não precisa dar vários echos no no select, não tem valor dinâmicro dentro dele, então você poderia simplesmente colocar o HTML direto.

4 - Seu insert tá fazendo um novo registro com apenas o dado do imc, ao invés do status.

Tá, como concertar? Primeiro, vamos trocar o insert para um update:

$sql = "UPDATE pacientes set status = :status WHERE id = :id";

...

$result = $pdo_statement->execute( array(':status'=>$_POST['status'] , ':id' => $_POST['id']));

Certo, agora vamos ajustar o HTML:


<div class="table-responsive">
    <table class="table table-striped table-bordered">
        <thead>
            <tr>
                <th> Data </th>
                <th> Nome </th>
                <th> Peso (kg) </th>
                <th> Altura </th>
            </tr>
        </thead>

        <tbody>
            <?php if(!empty($result)) : foreach($result as $row) : ?>

                <tr>
                    <td> <?php echo $row["data"];?> </td>
                    <td> <?php echo $row["nome"];?> </td>
                    <td> <?php echo $row["peso"];?> kg  </td>
                    <td> <?php echo $row["altura"]; ?> m  </td>
                    <td> <?php echo $row["imc"];  ?> </td>
                    <td>

                        <?php if($row["peso"] == '' ): ?>
                            <form name="myform" action="" method="POST"> 
                                <input type="hidden" name="id" value="<?php echo $row['id'] ?>">      
                                <select name='status' style='width: 125px; height: 35px;'>
                                    <option value='' selected disabled>  Justificativa   </option>
                                    <option value='Atrasado'>   Atrasado   </option>
                                    <option value='Falta'> Dispensado </option>
                                </select>
                                <div>
                                    <input type="submit" name="save_record" id="btnSubmit1" class="btn btn-primary" value="Salvar">
                                    <input type="submit" id="cancelar" class="btn btn-danger value="Corrigir" onclick="javascript:corrigir();">
                                </div>
                            </form> 
                        <?php endif; ?>

                    </td>
                </tr>

            <?php endforeach;  endif; ?>
        </tbody>    
    </table>
</div>

Movi o form para dentro do if, pra ele ser criado somente quando for preciso. Adicionei o campo id, para que se consiga diferenciar um registro do outro e atualizar o registro correto e assumo que esse campo exista na sua tabela. Caso não, você vai precisar criar como chave primeira e de auto incremento.

Deu pra entender mais ou menos o problema e a solução? Me conta como foi? Talvez você precise mudar alguma coisa :)

Aguardo resposta

Boa noite, Wanderson! Estou bem e você?

Muito obrigado pelo retorno, hoje tive um dia cheio e não tive tempo de testar o que você me passou, mas amanhã sem falta dou um retorno quanto a solução do problema. Abraços

Boa noite, Wanderson! Estou bem e você?

Muito obrigado pelo retorno, hoje tive um dia cheio e não tive tempo de testar o que você me passou, mas amanhã sem falta dou um retorno quanto a solução do problema. Abraços

Boa tarde, Wanderson! Não deu certo a solução que você sugeriu, deixe-me explicar melhor o que eu preciso fazer.

1- Tenho uma lista de pacientes que responderão a um questionário diariamente (antes e depois dos treinos).

2- As respostas do questionário ficarão disponíveis em uma outra página para que o relatório seja visualizado e nesta mesma página, caso o paciente não tenha respondido o questionário, abrirá o select para que o responsável pelo setor informe o por quê não foi respondido (conforme mostrado acima, atrasado, falta, etc).

3- Com as alterações do responsável do setor eu preciso criar mais uma página com o histórico de todas as datas em que o formulário foi respondido (com isso ainda precisarei fazer uma consulta através de um date range picker para selecionar uma data específica do histórico), mas isso é um assunto para outra hora.

Os problemas são os seguintes:

1- Como o formulário precisa ser respondido todo dia, deixar um id como chave primária acabou não dando certo, pois toda vez que tentava responder novamente, falava que a chave estava duplicada. A solução que achei pra resolver esse problema (não sei se da forma correta, foi deixar a data como chave primária, para que não houvesse duplicações).

2- Não consigo salvar o nome do paciente e o resultado do select na tabela do banco. Pois na tabela só aparecem quem os pacientes que responderam ao questionário.

3- Com o update que você sugeriu eu não consigo atrelar o id do paciente com o select e salvar na tabela, pois o id do paciente advém de uma chave estrangeira.

4- Gostaria de mostrar apenas um botão de salvar e não um a cada select que é aberto pela falta de informações do formulário.

Enfim, estes são os meus problemas, não sei se consegui deixar claro, pois são muitas informações, mas caso tenha ficado alguma dúvida, eu posso te enviar todo o código por e-mail (se ficar mais fácil). Aguardo o seu retorno, muito obrigado!

Oi João, tudo bem? Deixa eu dar minha opnião sobre os pontos.

1 - Sim, o id deveria ser sua chave primaria, não a data, os registros precisam estar separados, eu vou ter um id pra pessoa que respondeu, isso pra não precisar repetir dados dele em mais de um lugar. Agora a resposta do formulário deve estar em uma tabela que informa a data e o id da pessoa que respondeu como chave estrangeira.

2 - Não entendi o problema aqui.

3 - Sim, deve ser assim mesmo, mas pra pegar o id, você precisa fazer um join das duas tabelas (temos isso nos cursos de MySQL, principalmente no curso II)

4 - Acho justo fazer isso, são bem menos botões, mas você precisa de uma estratégia pra não acabar salvando o valor de um registro pra todos os da tabela. Uma ideia pode ser justar o status com o id no name do campo... então você teria: status_45 por exemplo, mas antes de executar a query, você teria que separar o status do id pra fazer os updates corretamentes. Faz sentido?

Boa tarde Wanderson, tudo bem? Fiquei um pouco perdido nas soluções, se você não se importa, gostaria de filtrar por partes até que tudo seja solucionado, tudo bem por você? A primeira parte do problema está em relação a chave primária, então vamos lá.

As minhas tabelas no banco de dados estão da seguinte forma:

Tabela pacientes, onde nela constam apenas o id (PK) e o nome do paciente.

Tabela pré-treino, onde nela constam as respostas que são obtidas através do formulário, sua estrutura é a seguinte: data (PK), id, peso, status e nomepaciente (aqui é a chave estrangeira da tabela pacientes, para que possa ser exibido o nome do paciente ao fazer um INNER JOIN nos relatórios).

Desta forma, como devo fazer para que o id da tabela pré-treino seja a PK dela e que com isso não dê o erro de duplicação que mencionei acima?

solução!

Então João, você precisa separar essas coisas. O id da resposta do questionário é a chave primaria, não a data. Então nesse sentido, você vai ter um registro para aquela data relativa ao paciente.

Certo, mas isso gera duplicação.

O problema é que, você não deve reusar o id das respostas do formulário para identificar o paciente.

Então, o id se refere a resposta do paciente naquele dia, e você terá um outro campo (que pode se repetir) que é o id do paciente. Aqui é o conceito de chave estrangeira, ou seja, o id da tabela paciente será usada na tabela de pré-treinos de forma que pode se repetir.

Ficou mais clara essa parte?

Boa tarde, Wanderson! Demorei para dar um retorno, pois ainda estava procurando o meu erro, e depois de muito tempo, graças as aulas e ao seu toque consegui identificar o que eu estava fazendo de errado para duplicar a resposta do formulário e também resolver a questão da PK. Ao invés de eu pegar o id da url e relacioná-la com a FK do paciente, eu estava pegando com o id da tabela pré-treino, e com isso acontecia o erro. Agradeço pelo auxílio, vou encerrar este tópico e com relação ao select se eu não achar uma solução volto a abrir um novo tópico. E novamente, muito obrigado!!!

Boa João, se precisar, estamos por aqui.