Th3Alchemist Posted March 21, 2012 at 04:17 PM Report #444929 Posted March 21, 2012 at 04:17 PM Boas! Estou com uma dúvida em termos de elaboração de uma query: Quero que um utilizador defina as suas horas de trabalho, num horário semanal, então da base de dados criei a seguinte tabela: HORARIO: - HR_ID (int): PK - UT_ID (int): FK (utilizador ID) - HR_diasem (tinyint) (dia da semana 0-6) - HR_horae (time) (hora entrada) - HR_horas (time) (hora saida) Agora o prolema que me surgiu é que caso que o utilizador nunca tenha inserido o horário de um dia, deverá ser executado um INSERT INTO. Caso que o utilizador esteja somente a actualizar o seu horario deverá ser feito um UPDATE. Elaborei o seguinte código (PHP): if ($database->quick_num("SELECT horario.HR_ID FROM horario WHERE horario.UT_ID = '$id' AND horario.HR_diasem = '$dias'") == 1) { $database->query("UPDATE horario SET horario.HR_horae = '$horae',horario.HR_horas = '$horas' WHERE horario.UT_ID = '$id' AND horario.HR_diasem = '$dias'"); } else { $database->query("INSERT INTO horario (horario.UT_ID, horario.HR_diasem, horario.HR_horae, horario.HR_horas) VALUES ('$id','$dias','$horae','$horas')"); } Minha dúvida é se é possível executar uma query só para obter o mesmo resultado? Do género INSERT IF NOT EXSIST else UPDATE... Estou a utilizar MySQL e esta é a única documentação que encontrei referente ao meu problema: http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html Também já me referiram em utilizar Routines, e caso que isso seja a melhor opção agradecia ajuda.
mjamado Posted March 21, 2012 at 04:28 PM Report #444932 Posted March 21, 2012 at 04:28 PM Colocas o campo HR_diasem como UNIQUE e depois já podes usa a sintaxe ON DUPLICATE KEY UPDATE. É a maneira mais fácil de fazer isto. "Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.
pmg Posted March 21, 2012 at 04:34 PM Report #444935 Posted March 21, 2012 at 04:34 PM Se não te importas em perder compatibilidade, usa o REPLACE do MySQL. $sql_statement = "replace INTO horario (UT_ID, HR_diasem, HR_horae, HR_horas) " . "VALUES ($id, $dias, '$horae', '$horas')" What have you tried? Não respondo a dúvidas por PM A minha bola de cristal está para compor; deve ficar pronta para a semana. Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!
Th3Alchemist Posted March 21, 2012 at 05:54 PM Author Report #444953 Posted March 21, 2012 at 05:54 PM Ok obrigado! Questão resolvida!
Th3Alchemist Posted March 21, 2012 at 11:17 PM Author Report #445036 Posted March 21, 2012 at 11:17 PM Desculpem me, afinal meter o HR_diasem como UNIQUE não vai poder ser possível... Pois existem vários utilizadores diferentes a definir o seu horário nessa mesma tabela... ou seja, o HR_diasem vai se repetir conforme o utilizador...
mjamado Posted March 22, 2012 at 12:36 AM Report #445062 Posted March 22, 2012 at 12:36 AM Percebi mal o problema, mas agora já entendi. O problema é que tens a BD mal normalizada, e depois dá estas dores de cabeça. Repara uma coisa: tens, essencialmente, duas tabelas principais neste sub-problema, a tabela dos utilizadores, e a dos dias da semana. A tabela dos dias da semana não existe fisicamente na base de dados, mas existe conceptualmente como entidade. O que tu queres é uma associação de muitos para muitos entre estas duas tabelas, associação essa que se faz com uma tabela auxiliar de chave dupla. Como essa relação tem dados associados, em teoria, e cumprindo a normalização até ao fim, existiria uma quarta tabela com o horário (sem chaves estrangeiras), e a chave dessa existiria como chave estrangeira na tabela auxiliar. Assim: [dias_semana] -|------|< [aux_dias_utilizadores] >|------|- [utilizadores] dia_id* dia_id* utilizador_id* nome utilizador_id* nome ... horario_id [FK] ... [horarios] horario_id* entrada saida ... Na prática, pode-se "desnormalizar" um bocadinho a tabela, que facilita nas queries: [dias_semana] -|------|< [horarios] >|------|- [utilizadores] dia_id* dia_id* utilizador_id* nome utilizador_id* nome ... entrada ... saida ... E agora, sim, podes usar o ON DUPLICATE KEY UPDATE, assim (minha estrutura): INSERT INTO horarios SET dia_id = :dia_id, utilizador_id = :utilizador_id, entrada = :entrada, saida = :saida ON DUPLICATE KEY UPDATE entrada = :entrada, saida = :saida "Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.
Th3Alchemist Posted March 22, 2012 at 10:55 AM Author Report #445090 Posted March 22, 2012 at 10:55 AM mjamado, segui o teu exemplo, mas a query não substitui os dados: UT_ID DIA_ID ENTRADA SAIDA 1 1 09:00:00 18:00:00 1 2 09:00:00 13:00:00 1 1 14:00:00 18:00:00 Não defeni nenhuma chave como UNIQUE suponho que falta isso?
mjamado Posted March 22, 2012 at 11:26 AM Report #445095 Posted March 22, 2012 at 11:26 AM mjamado, segui o teu exemplo, mas a query não substitui os dados: UT_ID DIA_ID ENTRADA SAIDA 1 1 09:00:00 18:00:00 1 2 09:00:00 13:00:00 1 1 14:00:00 18:00:00 Não defeni nenhuma chave como UNIQUE suponho que falta isso? Não, tens é as chaves primárias mal definidas: a chave primária é dupla! Tanto UT_ID como DIA_ID são chave primária. Repara na minha estrutura: as chaves primárias são as que têm asterisco à frente. "Para desenhar um website, não tenho que saber distinguir server-side de client-side" - um membro do fórum que se auto-intitula webdesigner. Temo pelo futuro da web.
Th3Alchemist Posted March 22, 2012 at 12:47 PM Author Report #445122 Posted March 22, 2012 at 12:47 PM mjamado, obrigado mais uma vez! Já funciona na perfeição!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now