VALIDANDO UM INSERTE COM EXISTS
Boa tarde pessoal,
Tenho um script aqui que insere numa tabela vários registros (tabela de configurações)
A medida que o sistema vai tendo novos recursos, deixo ativo (ou nao) aquele recurso em algum cliente
enfim...
Normalmente insiro assim no MSSMS
INSERT INTO configuracao (config_nome, config_valor) VALUES ("CONFIMPNFCE", "SIM")
Até ai normal, porem já me deparei varias vezes com a situação de inserir valores duplicados... isso vai dar bug na hora que a abrir a parte do recurso que vai verificar se tá ativo para aquele cliente...
Então pensei em verificar a existencia do na tabela antes de inserir... pensei em algo assim:
porem alem de não funcionar, ficou 5 linhas... e precisava algo mais "clean" numa linha
tipo
Se NÃO tem o valor XXX entao inserir XXX
Tenho um script aqui que insere numa tabela vários registros (tabela de configurações)
A medida que o sistema vai tendo novos recursos, deixo ativo (ou nao) aquele recurso em algum cliente
enfim...
Normalmente insiro assim no MSSMS
INSERT INTO configuracao (config_nome, config_valor) VALUES ("CONFIMPNFCE", "SIM")
Até ai normal, porem já me deparei varias vezes com a situação de inserir valores duplicados... isso vai dar bug na hora que a abrir a parte do recurso que vai verificar se tá ativo para aquele cliente...
Então pensei em verificar a existencia do na tabela antes de inserir... pensei em algo assim:
IF EXISTS (SELECT config_nome FROM configuracao WHERE (config_nome = "CONFIMPNFCE"))
"FAZ NADA
ELSE
INSERT INTO configuracao (config_nome, config_valor) VALUES ("CONFIMPNFCE", "SIM")
END IF
porem alem de não funcionar, ficou 5 linhas... e precisava algo mais "clean" numa linha
tipo
Se NÃO tem o valor XXX entao inserir XXX
Dependendo do banco de dados, essa funcionalidade já existe. Qual o banco de dados está usando?
Citação::
Dependendo do banco de dados, essa funcionalidade já existe. Qual o banco de dados está usando?
Sql Server Express 2008
Não precisa fazer pesquisa alguma. Voce tem que tratar isso com chave primária nos campos que não podem haver repetição. DaÃÂ, quando for inserir e os dados forem repetidos, vai gerar uma exceção na aplicação.
Citação::
Não precisa fazer pesquisa alguma. Voce tem que tratar isso com chave primária nos campos que não podem haver repetição. DaÃÂ, quando for inserir e os dados forem repetidos, vai gerar uma exceção na aplicação.
Seria realmente o mais indicado.
Mais caso eu quisesse fazer o EXISTS e depois o INSERT
Citação::
Mais caso eu quisesse fazer o EXISTS e depois o INSERT
Voce não pode fazer assim porque pode gerar problema de concorrencia. Ou seja, duas pesquisas poderão ser feitas quase que ao mesmo tempo e ambas passarem na verificação, daàna hora de inserirem, vai gerar duplicação.
O que voce se refere, é um anti-pattern, chamado UPSERT e é na prática uma má idéia, mas se voce quer mesmo fazer, sugiro usar algo assim:
É um dos modos mais seguros de fazer o que voce quer porque amarra uma transação.
CREATE PROCEDURE s_ConfigNome_Upsert ( @Nome nvarchar(4000), @Config nvarchar(max) )
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
MERGE dbo.configuracao AS myTarget
USING (SELECT config_nome FROM configuracao WHERE (config_nome = @Nome)) AS mySource
ON mySource.config_nome = myTarget.config_nome
WHEN MATCHED THEN UPDATE
SET config_valor = mySource.config_valor
WHEN NOT MATCHED THEN
INSERT INTO configuracao (config_nome, config_valor) VALUES (@Nome, @Config)
É um dos modos mais seguros de fazer o que voce quer porque amarra uma transação.
Citação::
O que voce se refere, é um anti-pattern, chamado UPSERT e é na prática uma má idéia, mas se voce quer mesmo fazer, sugiro usar algo assim:
CREATE PROCEDURE s_ConfigNome_Upsert ( @Nome nvarchar(4000), @Config nvarchar(max) )
AS
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
MERGE dbo.configuracao AS myTarget
USING (SELECT config_nome FROM configuracao WHERE (config_nome = @Nome)) AS mySource
ON mySource.config_nome = myTarget.config_nome
WHEN MATCHED THEN UPDATE
SET config_valor = mySource.config_valor
WHEN NOT MATCHED THEN
INSERT INTO configuracao (config_nome, config_valor) VALUES (@Nome, @Config)
É um dos modos mais seguros de fazer o que voce quer porque amarra uma transação.
Desculpe a demora, tive q fazer um estagio e nao tive mais tempo... retornei hoje
Executei e deu o seguinte erro:
[txt-color=#e80000]Mensagem 156, NÃÂvel 15, Estado 1, Procedimento s_ConfigNome_Upsert, Linha 12
Sintaxe incorreta próxima àpalavra-chave "INTO".[/txt-color]
Tópico encerrado , respostas não são mais permitidas