Insert ou Update ?

Forum sobre SQL.

Moderador: Moderadores

rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá,

Como seria uma sentença em SQL para se fazer um Insert ou um update caso o registro já exista ?

Já vi que existe duas formas que são o "replace" e o "insert ... on duplicate key", mas pelo que entendi, ambos precisam de um "primary Key" e eu não estou trabalhando com "primary Key", então teria como fazer isto em uma única sentença ?

Obrigado,
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

No MySQL tem o INSERT IGNORE

Se está dizendo sobre o teste, seria fazer um SELECT antes do INSERT pra testar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá José,

Eu preciso que caso não exista o registro, ele seja inserido ou senão seja atualizado tipo "update".

Este comando "INSERT IGNORE" faz isso, ou se já existe o registro, não faz nada e retorna um erro de execução ?

Obrigado,
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá,

Como estou iniciando um novo projeto, preferi criar as chaves primárias pra deixar o SQL controlar isto, e com isto posso usar o comando "Replace Into"

Obrigado,
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá,

No caso ao criar a "Primary Key" eu já tinha um Index com os mesmos campos:

Código: Selecionar todos

ALTER TABLE `Tokens`
  ADD PRIMARY KEY (`A66_AUTO`,`A66_SEQU`),
  ADD KEY `indice_princ` (`A66_AUTO`,`A66_SEQU`);
COMMIT;
Neste caso, há a necessidade de se criar este index "indice_princ" para agilizar as pesquisas, ou não precisa disto ?

Obrigado,
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

Um índice principal agiliza tudo no MySQL, mesmo que não seja usado.

Estou achando estranho o seguinte:
Como o MySQL vai saber se está duplicado sem uma chave de referência?
Ou quem ele vai atualizar sem saber qual é a chave?

Nota:

Tive certeza disso de índice numa base de uma pessoa aqui do fórum, a tabela dele tinha 100GB e não tinha índice nenhum.
Pra excluir um único registro demorava até horas.
Justamente ele estava tentando limpar a base pra deixar mais rápido.

Depois de criar um índice primário, a exclusão passou a ser quase instantânea.
E a exclusão nem usava índice nenhum, nem tinha a ver com criar índice pela chave de acesso, era exclusão direta no HeidiSQL marcando registros e excluindo.
Lógico... no caso de usar chave de acesso com índice, muito melhor e mais rápido.

Então:

1) Acostume a criar um índice pela chave primária SEMPRE, de preferência um campo incremental.
2) Ter uma chave única para a tabela é importantíssimo, mesmo se decidir não usar como chave, por exemplo numa tabela de UFs, onde a chave principal é a sigla.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá José,

Obrigado pelas informações, irei adotar o esquema de sempre criar os índices, tanto "primários", ou para ordenar por exemplo por "nome" para agilizar na hora de pesquisa por "nome".
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Insert ou Update ?

Mensagem por alxsts »

Olá!
rossine escreveu:Neste caso, há a necessidade de se criar este index "indice_princ" para agilizar as pesquisas, ou não precisa disto ?
Não, não precisa. Se você criar uma primary key para a tua tabela, o que é altamente recomendável, isto já será seu índice principal. Criar a primary key e um índice adicional com as mesmas colunas da PK será uma redundância e desperdício de recursos do sistema...
JoséQuintas escreveu:Então:
1) Acostume a criar um índice pela chave primária SEMPRE, de preferência um campo incremental.
Isto não ficou claro para mim. Você recomenda criar a PK e o índice? Ou "criar um índice pela chave primária" quer dizer criar a PK?

Lembrando que uma primary key não aceita valores duplicados ou NULL e que cada tabela pode ter apenas uma primary key. Prymary keys são semelhantes aos unique indexes mas, estes últimos podem conter NULL e uma tabela pode ter mais de um unique index. Procure evitar primary keys compostas (formadas por mais de uma coluna).
rossine escreveu:Já vi que existe duas formas que são o "replace" e o "insert ... on duplicate key"
Além das formas que você citou, existe o INSERT IGNORE, citado anteriormente.

Evite usar REPLACE. Este comando, quando necessário (quando já existe a linha desejada), ele faz um DELETE E depois um INSERT, consumindo mais recursos que um INSERT ... ON DUPLICATE KEY UPDATE que faz um INSERT OU UPDATE, como no exemplo abaixo.

Código: Selecionar todos

INSERT INTO books
    (id, title, author, year_published)
VALUES
    (@id, @title, @author, @year_published)
ON DUPLICATE KEY UPDATE
    title = @title,
    author = @author,
    year_published = @year_published;
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

alxsts escreveu:Isto não ficou claro para mim. Você recomenda criar a PK e o índice? Ou "criar um índice pela chave primária" quer dizer criar a PK?
Ter sempre uma PRIMARY KEY única, de preferência incremental.
Se tiver mais índices, vai ser pra agilizar determinadas consultas/filtros.
importante: no SQL, índices são pra consultas/filtros, e não pra relatório em ordem alfabética, por exemplo.

Muito antigamente o MySQL permitia chave composta pra índice incremental, nem sei se isso ainda existe, acho que foi removido.
E esse índice PRIMARY KEY pode até se tornar obrigatório, por enquanto mostram mais como recomendação.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

Não entendi esse ON UPDATE, porque tá parecendo stored procedure.
Deve necessitar a definição de variáveis primeiro.
Ou vai precisar um comando grande, repetindo os campos, apesar disso não ser problema.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Insert ou Update ?

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Ter sempre uma PRIMARY KEY única, de preferência incremental.
Se tiver mais índices, vai ser pra agilizar determinadas consultas/filtros.
Agora entendi o que quis dizer. PRIMARY KEY são sempre únicas dentro da mesma tabela.
JoséQuintas escreveu:no SQL, índices são pra consultas/filtros, e não pra relatório em ordem alfabética, por exemplo.
Eventualmente servem para ORDER BY também, se for mais barato usar o índice do que fazer a operação FileSort. Veja ORDER BY Optimization. Portanto, se quiser um relatório de clientes ordenado alfabeticamente e a tabela tiver o índice disponível, ele vai ser utilizado. O mesmo ocorre com GROUP BY (veja GROUP BY Optimization) e provavelmente com HAVING, visto que este último precisa do GROU BY.
JoséQuintas escreveu:Não entendi esse ON UPDATE, porque tá parecendo stored procedure.
Deve necessitar a definição de variáveis primeiro.
Ou vai precisar um comando grande, repetindo os campos, apesar disso não ser problema.
Depende da situação, pode usar o comando colocando os valores literais (por exemplo, no HeidiSQL) ou passar parâmetros para uma stored procedures e usar como variáveis para depois executar com PREPARE e EXECUTE, ou até montar uma string no Harbour, concatenando os valores e depois executando...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

alxsts escreveu:Eventualmente servem para ORDER BY também, se for mais barato usar o índice do que fazer a operação FileSort. Veja ORDER BY Optimization. Portanto, se quiser um relatório de clientes ordenado alfabeticamente e a tabela tiver o índice disponível, ele vai ser utilizado.
Confusa a explicação do link.
Chamou a atenção numa parte, onde diz que se todos os campos estão no índice, é usado somente o índice - isso é algo conhecido em DBF.
De resto parece muito eventual.
alxsts escreveu:O mesmo ocorre com GROUP BY (veja GROUP BY Optimization) e provavelmente com HAVING, visto que este último precisa do GROU BY.
Discordo da comparação, são coisas distintas.
GROUP BY tem a ver com filtro e não com ordem.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Insert ou Update ?

Mensagem por alxsts »

Olá!
JoséQuintas escreveu:Discordo da comparação, são coisas distintas.
GROUP BY tem a ver com filtro e não com ordem.
discordando ou não, há situações onde o índice é usado no GROU BY, conforme consta no manual (link acima).

Edit:
Ah... GROUP BY não tem nada a ver com filtro e sim com agrupamento. Filtro é WHERE (filtra linhas) e HAVING (filtra grupos de linhas após o GROUP BY )...
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Insert ou Update ?

Mensagem por JoséQuintas »

alxsts escreveu:discordando ou não, há situações onde o índice é usado no GROU BY, conforme consta no manual (link acima).
Edit:
Ah... GROUP BY não tem nada a ver com filtro e sim com agrupamento. Filtro é WHERE (filtra linhas) e HAVING (filtra grupos de linhas após o GROUP BY )...
Na primeira parte, ao me referir que GROUP BY faz parte do filtro, vale o que eu disse que índice pode ser usado pra agilizar filtro, apesar do GROUP BY realmente não ser filtro.

Na segunda parte tenho dúvidas sobre o HAVING, porque teoricamente o HAVING depende dos cálculos do GROUP BY, então a otimização vai ser antes dele ser usado..
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Insert ou Update ?

Mensagem por rossine »

Olá,

Alxsts, irei estudar a possibilidade de usar o "Insert ... On Duplicate Key...."

Obrigado a todos pelas informações e dicas,
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
Responder