none
CRUD-SQL Dar update em um campo apenas RRS feed

  • Pergunta

  • Olá a todos,

    Minha dúvida é a seguinte, estou aprendendo sobre procedures e estou criando um crud com elas, porém, gostaria de saber como faço um update em um campo só mantendo os dados antigos sem alteração. Exemplo:
    Tenho uma tabela aluno, onde nela existe id,nome,email,telefone já com dados 1,"Joao","joao@email.com",999999999. gostaria de alterar o telefone deste cadastro mas mantendo seus antigos dados, sem precisar escrever tudo novamente do mesmo jeito que estava antes, alguma dica?

    Grato desde já!

    terça-feira, 4 de junho de 2019 13:16

Respostas

  • Bom dia,

    Douglas, não sei se entendi corretamente a sua questão, mas uma alternativa que costuma ser utilizada e talvez seja útil no seu caso é a definição de null como valor padrão para os parâmetros e o uso da função Coalesce ou IsNull para retornar o valor original da coluna quando o parâmetro for nulo. Ex:

    CREATE PROC atualiza_aluno
    
    @id int,
    @nome varchar(200) = null,
    @email varchar(200) = null,
    @telefone int = null
    
    as
    
    begin
    
    update aluno 
    set 
        nomeAluno = coalesce(@nome, nomeAluno), 
        emailAluno = coalesce(@email, emailAluno), 
        telefoneAluno = coalesce(@telefone, telefoneAluno)
    where 
        idAluno = @id
    
    end

    No exemplo acima, os parâmetros @nome e @email ficarão nulos se for preenchido somente o parâmetro @telefone e os valores das colunas nomeAluno e emailAluno serão mantidos.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    • Marcado como Resposta Douglas Souza05 terça-feira, 4 de junho de 2019 16:30
    terça-feira, 4 de junho de 2019 14:30

Todas as Respostas

  • Douglas,

    Se eu entendi bem, você deseja somente alterar a coluna Telefone? Se for isso, entendo que um simples comando Update poderá lhe ajudar, veja o exemplo:

    -- Atualizando a coluna Telefone --
    Update Aluno
    Set Telefone = '88888888'
    Where CodigoAluno = 1

    Agora se por acaso você deseja fazer a alteração e armazenar em outra tabela os dados antigos, acredito que a cláusula Output poderá lhe ajudar, veja este exemplo:

    -- Criando a Table Alunos --
    Create Table Alunos
     (CodigoAluno SmallInt Identity Primary Key Clustered,
      NomeAluno VarChar(20) Not Null,
      DataNascimentoAluno Date Not Null,
      TelefoneAluno Char(9) Null)
    Go
    
    Insert Into Alunos (NomeAluno, DataNascimentoAluno, TelefoneAluno)
    Values('Pedro','1980-04-28','9999-9999'),
          ('Galvão','1980-04-28','8888-8888'),
          ('Junior','1980-04-28','7777-7777')
    Go
    
    
    -- Criando a Tabela AlunosAlteracoes --
    Create Table AlunosAlteracoes
     (CodigoAluno SmallInt Primary Key Clustered,
      NomeAluno VarChar(20) Not Null,
      DataNascimentoAluno Date Not Null,
      TelefoneAluno Char(9) Null)
    Go
    
    -- Registrando as alterações de Alunos em AlunosAlteracoes --
    Update Alunos
    Set TelefoneAluno = '6666-6666'
     Output deleted.CodigoAluno, deleted.NomeAluno, deleted.DataNascimentoAluno, deleted.TelefoneAluno
     Into AlunosAlteracoes
    Where CodigoAluno = 3
    Go
    
    -- Consultando os dados na Tabela AlunosAlteracoes --
    Select * From AlunosAlteracoes
    Go

    Quando utilizamos a cláusula Output o SQL Server criar em tempo de execução desta cláusula duas tabelas temporárias: Inserted e Deleted:

    •  Inserted - Contem a posição com os valores novos que serão inseridos ou atualizados; e
    • Delelted - Contem a posição dos dados antigos, que foram excluídos ou atualizados.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 4 de junho de 2019 13:34
  • Bom dia Junior!

    Seria a primeira situação, mas com uma procedure, está assim:

    CREATE PROC atualiza_aluno

    @id int,

    @nome varchar(200),

    @email varchar(200),

    @telefone int

    as

    begin

    update aluno set nomeAluno = @nome, emailAluno = @email, telefoneAluno = @telefone

    where idAluno = @id

    end

    Eu gostaria apenas de alterar o telefone, mas sem alterar oq ja está incluso(nome, email, etc), imaginei um for para checar oq foi alterado mas não sei se é possível nem como começar, entende?

    Obrigado!

    terça-feira, 4 de junho de 2019 13:47
  • Douglas,

    Ainda fiquei na dúvida, esta procedure vai atualizar somente o telefone, ou poderemos alterar todas as colunas?

    Se por isso somente o telefone é um cenário, se for considerarmos as outras colunas é outra possibilidade.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 4 de junho de 2019 13:56
  • A ideia é ter uma procedure que possa tanto atualizar todos os dados quanto atualizar apenas um, porém, quando quero atualizar apenas um, preciso colocar novamente todos os dados iguais aos que já estavam no cadastro pois estão como parâmetros e são de preenchimento obrigatório.
    terça-feira, 4 de junho de 2019 13:57
  • Douglas,

    Ok, mas quando realizamos um Update e vamos manipular somente os dados de algumas colunas, o SQL Server em hipótese alguma altera os dados das colunas não declaradas.

    Bom, eu montei um Código de exemplo, não é a melhor solução, mas é um esboço do que podemos pensar em fazer:

    CREATE PROC atualiza_aluno @CodigoAluno int, @Nome varchar(200), @DataNascimentoAluno Date, @Telefone char(9)
    As
    Begin
    
    Set NoCount On
    
     Declare @NomeAtual varchar(200),
             @DataNascimentoAlunoAtual Date,
    		 @TelefoneAtual Char(9)
    
     Select @NomeAtual=NomeAluno, 
            @DataNascimentoAlunoAtual = DataNascimentoAluno,
            @TelefoneAtual= TelefoneAluno
     From Alunos
     Where CodigoAluno = @CodigoAluno
    
    If (@Nome <> @NomeAtual) And (@DataNascimentoAluno <> @DataNascimentoAlunoAtual) And (@Telefone = @TelefoneAtual)
    Begin
    
    Update Alunos
    Set NomeAluno = @Nome,
        DataNascimentoAluno = @DataNascimentoAluno,
    	TelefoneAluno = @Telefone
    Where CodigoAluno = @CodigoAluno
    
    End
    Else If (@Nome <> @NomeAtual) And (@DataNascimentoAluno <> @DataNascimentoAlunoAtual)
    Begin
    
    Update Alunos
    Set NomeAluno = @Nome,
        DataNascimentoAluno = @DataNascimentoAluno
    Where CodigoAluno = @CodigoAluno
    
    End
    Else If (@Nome <> @NomeAtual)
    Begin
    
    Update Alunos
    Set NomeAluno = @Nome
    Where CodigoAluno = @CodigoAluno
    
    End
    Else If (@DataNascimentoAluno <> @DataNascimentoAlunoAtual)
    Begin
    
    Update Alunos
    Set DataNascimentoAluno = @DataNascimentoAluno
    Where CodigoAluno = @CodigoAluno
    
    End
    Else 
    Begin
    
    Update Alunos
    Set TelefoneAluno = @Telefone
    Where CodigoAluno = @CodigoAluno
    
    End
    End

    Repito este é um esboço, temos muito a melhorar na estrutura, condições e até mesmo na forma de analisar as manipulações dos dados.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 4 de junho de 2019 14:08
  • Boa Junior! Essa é a ideia que preciso, agora vou analisar como posso melhorar isso pois são muitos campos e não vai ficar nada legal colocar um monte de if para verificação, teria como usar o comando FOR nesses casos?
    terça-feira, 4 de junho de 2019 14:19
  • Bom dia,

    Douglas, não sei se entendi corretamente a sua questão, mas uma alternativa que costuma ser utilizada e talvez seja útil no seu caso é a definição de null como valor padrão para os parâmetros e o uso da função Coalesce ou IsNull para retornar o valor original da coluna quando o parâmetro for nulo. Ex:

    CREATE PROC atualiza_aluno
    
    @id int,
    @nome varchar(200) = null,
    @email varchar(200) = null,
    @telefone int = null
    
    as
    
    begin
    
    update aluno 
    set 
        nomeAluno = coalesce(@nome, nomeAluno), 
        emailAluno = coalesce(@email, emailAluno), 
        telefoneAluno = coalesce(@telefone, telefoneAluno)
    where 
        idAluno = @id
    
    end

    No exemplo acima, os parâmetros @nome e @email ficarão nulos se for preenchido somente o parâmetro @telefone e os valores das colunas nomeAluno e emailAluno serão mantidos.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    • Marcado como Resposta Douglas Souza05 terça-feira, 4 de junho de 2019 16:30
    terça-feira, 4 de junho de 2019 14:30
  • Perfeito! Funcionou exatamente como eu precisava, muito obrigado!
    terça-feira, 4 de junho de 2019 16:30
  • Bom dia,

    Douglas, não sei se entendi corretamente a sua questão, mas uma alternativa que costuma ser utilizada e talvez seja útil no seu caso é a definição de null como valor padrão para os parâmetros e o uso da função Coalesce ou IsNull para retornar o valor original da coluna quando o parâmetro for nulo. Ex:

    CREATE PROC atualiza_aluno
    
    @id int,
    @nome varchar(200) = null,
    @email varchar(200) = null,
    @telefone int = null
    
    as
    
    begin
    
    update aluno 
    set 
        nomeAluno = coalesce(@nome, nomeAluno), 
        emailAluno = coalesce(@email, emailAluno), 
        telefoneAluno = coalesce(@telefone, telefoneAluno)
    where 
        idAluno = @id
    
    end

    No exemplo acima, os parâmetros @nome e @email ficarão nulos se for preenchido somente o parâmetro @telefone e os valores das colunas nomeAluno e emailAluno serão mantidos.

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    Gapimex,

    Matou a pau, parabéns.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 4 de junho de 2019 17:12
  • Boa Junior! Essa é a ideia que preciso, agora vou analisar como posso melhorar isso pois são muitos campos e não vai ficar nada legal colocar um monte de if para verificação, teria como usar o comando FOR nesses casos?

    Douglas,

    Sim, eu simplesmente montei um exemplo, com base, na maneira que você estava descrevendo o seu post, por isso utilizei os IFs, ainda mais por você ter destacado o uso do FOR, pensei que estava querendo fazer análises condicionais.

    Mas faça uso do código do Gapimex, é mais simples, mais fácil de se entender, e com certeza vai funcionar melhor ainda.


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 4 de junho de 2019 17:14
  • Utilizei o código dele e o resto das validações vou fazer dentro do programa mesmo, muito obrigado por sua atenção e ajuda Junior!
    terça-feira, 4 de junho de 2019 18:48