Jump to content

INSERT IF NOT EXIST else UPDATE ??


Th3Alchemist
 Share

Recommended Posts

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
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
 Share

×
×
  • 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.