none
Passar NULL pro SQL Server RRS feed

  • Pergunta

  • Pessoal,

    Como faço para gravar NULL no banco, quando o campo não estiver preenchido?

    string.IsNullOrEmpty(campo) ? DBNull.Value : campo
    

    No exemplo acima, verifico se campo está vazio ou nulo. Se estiver, quero que grave NULL no banco. Só que nesse exemplo, o método espera um campo do tipo INT, se jogo DBNull.Value, gerando o erro:

    Type of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'int'

    Uma saída, seria gravar "0". Mas gostaria de gravar NULL no banco, tem como?

    terça-feira, 18 de janeiro de 2011 17:27

Respostas

  • Guilherme,

    O Sandro passou uma boa solução, mas costumo utilizar isto aqui.

    Parametro SQL.

    SqlParameter sp1 = new SqlParameter("@codigo", SqlDbType.Int);
    ConverterDbNull(ref sp1, campoCodigo.ToString());

    Função abaixo:

            public static void ConverterDbNull(ref SqlParameter sp, string value)
            {
                if ( sp.SqlDbType.Equals(SqlDbType.VarChar))
                {
                    if (string.IsNullOrEmpty(value)) sp.Value = DBNull.Value;
                    else sp.Value = value;
                }
                else if (sp.SqlDbType.Equals(SqlDbType.Int))
                {
                    if (string.IsNullOrEmpty(value)) sp.Value = DBNull.Value;
                    else sp.Value = Int32.Parse(value);
                }
            }

    Abraço

    Estevam


    **** Se a reposta foi útil, então não esqueça de marca-lá. ***
    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:33
    terça-feira, 18 de janeiro de 2011 19:08
  • ola

    se estiver usando o .NET 2.0 ou superior, vc pode utilizar os nullable types

    na declaração do seu método, informe que o parametor pode ser nulo, assim, informando ? no tipo

    private void gravar(string nome, int? valor )

    {

    }

    se for o 1.1, não tem jeito.. vc vai ter que passar o parâmetro como inteiro (0 ou -1) e comparar e passar somente se for diferente destes valores...

    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:33
    terça-feira, 18 de janeiro de 2011 18:18
  • A sim, agora ficou claro.

    Isso deve estar acontecendo devido a maneira que voce esta passando o parametro para o método. para valores nullables, voce nao pode efetuar o if dessa maneira na passagem do parametro.

    voce precisa fazer isso para todos os parametro nullables:

    int? _seguradora = null;
    
    if(!string.IsNullOrEmpty(txtSeguradora.Text))
       _seguradora = Convert.ToInt32(txtSeguradora.Text);
    
    
    

    ai no seu método voce passa a variavel _seguradora ao invés de realizar o if dentro do parametro.

    Um abraço


    ----------------------------
    Bruno Seixas
    Analista de Sistemas
    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:34
    quarta-feira, 19 de janeiro de 2011 14:37

Todas as Respostas

  • ola

    se estiver usando o .NET 2.0 ou superior, vc pode utilizar os nullable types

    na declaração do seu método, informe que o parametor pode ser nulo, assim, informando ? no tipo

    private void gravar(string nome, int? valor )

    {

    }

    se for o 1.1, não tem jeito.. vc vai ter que passar o parâmetro como inteiro (0 ou -1) e comparar e passar somente se for diferente destes valores...

    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:33
    terça-feira, 18 de janeiro de 2011 18:18
  • Guilherme,

    O Sandro passou uma boa solução, mas costumo utilizar isto aqui.

    Parametro SQL.

    SqlParameter sp1 = new SqlParameter("@codigo", SqlDbType.Int);
    ConverterDbNull(ref sp1, campoCodigo.ToString());

    Função abaixo:

            public static void ConverterDbNull(ref SqlParameter sp, string value)
            {
                if ( sp.SqlDbType.Equals(SqlDbType.VarChar))
                {
                    if (string.IsNullOrEmpty(value)) sp.Value = DBNull.Value;
                    else sp.Value = value;
                }
                else if (sp.SqlDbType.Equals(SqlDbType.Int))
                {
                    if (string.IsNullOrEmpty(value)) sp.Value = DBNull.Value;
                    else sp.Value = Int32.Parse(value);
                }
            }

    Abraço

    Estevam


    **** Se a reposta foi útil, então não esqueça de marca-lá. ***
    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:33
    terça-feira, 18 de janeiro de 2011 19:08
  • Oi Sandro,

    Declarei os parametros, da forma que vc sugeriu, mas continua gerando o erro que mencionei. Tentei passar "DBNull.Value" e "null" para o parâmetro, mas ele não aceita com o nullable types.

    Estou usando o VS2010.

    quarta-feira, 19 de janeiro de 2011 09:58
  • Oi Luiz,

    Vou testar a sua dica!

    quarta-feira, 19 de janeiro de 2011 10:03
  • ola

    coloque o seu código aqui para ver como está.. O método e a chamada para ele...

    quarta-feira, 19 de janeiro de 2011 10:46
  • Chamada:

     

    string.IsNullOrEmpty(((DropDownList)this.ListView1.InsertItem.FindControl("ddlSeguradora")).SelectedValue) ? DBNull.Value : Convert.ToInt32(((DropDownList)this.ListView1.InsertItem.FindControl("ddlSeguradora")).SelectedValue)
    
    ou
    
    string.IsNullOrEmpty(((DropDownList)this.ListView1.InsertItem.FindControl("ddlSeguradora")).SelectedValue) ? null : Convert.ToInt32(((DropDownList)this.ListView1.InsertItem.FindControl("ddlSeguradora")).SelectedValue)
    

     

    Método:

     

    public int insereVeiculo(int? seguradora)
    {
    ...
    }
    
    

     

    quarta-feira, 19 de janeiro de 2011 10:53
  • Guilherme na sua base está aceitando null? Coloque seu método completo
    public
     int
     insereVeiculo

    Não esqueça de usar o componente </> na barra para posta seu código.
    quarta-feira, 19 de janeiro de 2011 11:20
    Moderador
  • Oi Seilor, a base está aceitando null sim. O meu problema, é que o método que não está aceitando a passagem do null.

    Segue método completo:

     public int insereVeiculo(
        int marca,
        int modelo,
        string placa,
        int condutor,
        string renavam,
        int anofabricacao,
        int local,
        int propriedade,
        string apolice,
        int? seguradora,
        DateTime? dtInicioSeguro,
        DateTime? dtFimSeguro,
        decimal? valorSeguro,
        string chassis,
        int SetorCusto,
        int anoModelo,
        string NF,
        decimal valorCompra,
        string codFIPE,
        decimal valorFIPE,
        int faixaIPVA,
        decimal valorIPVA,
        string foto,
        int usuario
        )
      {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["portal_sebandConnectionString"].ConnectionString);
        SqlCommand cmd = new SqlCommand("sbd_sp_veiculos_insere");
        cmd.Connection = con;
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@intMarca", SqlDbType.Int).Value = marca;
        cmd.Parameters.Add("@intModelo", SqlDbType.Int).Value = modelo;
        cmd.Parameters.Add("@txtPlaca", SqlDbType.VarChar, 50).Value = placa;
        cmd.Parameters.Add("@intCondutor", SqlDbType.Int).Value = condutor;
        cmd.Parameters.Add("@txtRenavam", SqlDbType.VarChar, 50).Value = renavam;
        cmd.Parameters.Add("@intAnoFabricacao", SqlDbType.Int).Value = anofabricacao;
        cmd.Parameters.Add("@intLocal", SqlDbType.Int).Value = local;
        cmd.Parameters.Add("@intPropriedade", SqlDbType.Int).Value = propriedade;
        cmd.Parameters.Add("@txtApolice", SqlDbType.VarChar, 50).Value = apolice;
        cmd.Parameters.Add("@intSeguradora", SqlDbType.Int).Value = seguradora;
        cmd.Parameters.Add("@dtInicioSeguro", SqlDbType.DateTime).Value = dtInicioSeguro;
        cmd.Parameters.Add("@dtVencimentoSeguro", SqlDbType.DateTime).Value = dtFimSeguro;
        cmd.Parameters.Add("@intVlSeguro", SqlDbType.Decimal).Value = valorSeguro;
        cmd.Parameters.Add("@txtChassis", SqlDbType.VarChar, 50).Value = chassis;
        cmd.Parameters.Add("@intSetorCusto", SqlDbType.Int).Value = SetorCusto;
        cmd.Parameters.Add("@intAnoModelo", SqlDbType.Int).Value = anoModelo;
        cmd.Parameters.Add("@txtNFCompra", SqlDbType.VarChar, 50).Value = NF;
        cmd.Parameters.Add("@valorCompra", SqlDbType.Decimal).Value = valorCompra;
        cmd.Parameters.Add("@codFipe", SqlDbType.VarChar, 50).Value = codFIPE;
        cmd.Parameters.Add("@valorVenalFipe", SqlDbType.Decimal).Value = valorFIPE;
        cmd.Parameters.Add("@faixaIPVA", SqlDbType.Int).Value = faixaIPVA;
        cmd.Parameters.Add("@valorVenalIPVA", SqlDbType.Decimal).Value = valorIPVA;
        cmd.Parameters.Add("@foto", SqlDbType.VarChar, 200).Value = foto;
        cmd.Parameters.Add("@intUsuario", SqlDbType.Int).Value = usuario;
        cmd.Parameters.Add("@retorno", SqlDbType.Int).Direction = ParameterDirection.Output;
        con.Open();
    
        cmd.ExecuteNonQuery();
    
        int retorno = Convert.ToInt32(cmd.Parameters["@retorno"].Value);
    
        con.Dispose();
        con.Close();
        cmd.Dispose();
        return retorno;
      }
    

    quarta-feira, 19 de janeiro de 2011 11:23
  • Olá, Guilherme.

    O seu método está aceitando null sim, nos parâmetros.O que você precisa agora é passar o null para o banco de dados.

    É importante entender que null e DBNull.Value são tipos totalmente diferentes. O valor nulo para o código C# é null, enquanto para o bd é DBNull.Value.

    Além disso, vale lembrar que você fez a utilização do seguinte ternário:

    string.IsNullOrEmpty(campo) ? DBNull.Value : campo

    Onde cada retorno, é um tipo de dados; e isso o ternário não aceita. É por isso que ocorre o erro postado.

    Para resolver todos os problemas, passe null para o método e na adição de parâmetros ao command, faça como o exemplo abaixo:

    if(seguradora.HasValue)
    {
     cmd.Parameters.Add("@intSeguradora", SqlDbType.Int).Value = seguradora.Value;
    }
    else
    {
     cmd.Parameters.Add("@intSeguradora", SqlDbType.Int).Value = DBNull.Value;
    }
    

    Abraços,


    Paulo Castilho - www.paulocastilho.com.br
    quarta-feira, 19 de janeiro de 2011 11:59
  • Oi Paulo,

    O meu problema, é que ele nem chega à adicionar os parâmetros no SQL Server no método. Ele gera erro antes, na chamada do método.

    quarta-feira, 19 de janeiro de 2011 12:12
  • oi,

    voce nao pode passar DBNull.Value no parametro nullable int?. todos os nullables esperam o valor origem no seu caso Int32 ou NULL.

    nao tem jeito, voce precisa passar null como parametro no inteiro e no seu codigo de inserção no banco voce verifica:

    if(seguradora.HasValue)
    {
     cmd.Parameters.Add("@intSeguradora", SqlDbType.Int).Value = seguradora.Value;
    }
    else
    {
     cmd.Parameters.AddWithValue("@intSeguradora", DBNull.Value);
    }
    
    


    ----------------------------
    Bruno Seixas
    Analista de Sistemas
    quarta-feira, 19 de janeiro de 2011 14:08
  • Oi Bruno, eu sei.. tentei das 2 formas. Com DBNull.Value e somente null. Mas ambas opções, gera o erro descrito.
    quarta-feira, 19 de janeiro de 2011 14:19
  • qual erro?

    eType of conditional expression cannot be determined because there is no implicit conversion between 'System.DBNull' and 'int'

    ele da esse erro quando voce passa null para a sua variavel int?

     

    int? i;

    i = string.IsNullOrEmpty(campo) ? null : Convert.ToInt32(campo);

     

    isso que esta gerando esse erro acima??


    ----------------------------
    Bruno Seixas
    Analista de Sistemas
    quarta-feira, 19 de janeiro de 2011 14:24
  • Para ilustrar o erro:

    quarta-feira, 19 de janeiro de 2011 14:29
  • A sim, agora ficou claro.

    Isso deve estar acontecendo devido a maneira que voce esta passando o parametro para o método. para valores nullables, voce nao pode efetuar o if dessa maneira na passagem do parametro.

    voce precisa fazer isso para todos os parametro nullables:

    int? _seguradora = null;
    
    if(!string.IsNullOrEmpty(txtSeguradora.Text))
       _seguradora = Convert.ToInt32(txtSeguradora.Text);
    
    
    

    ai no seu método voce passa a variavel _seguradora ao invés de realizar o if dentro do parametro.

    Um abraço


    ----------------------------
    Bruno Seixas
    Analista de Sistemas
    • Marcado como Resposta Guilherme_ quinta-feira, 20 de janeiro de 2011 00:34
    quarta-feira, 19 de janeiro de 2011 14:37
  • Putz, nem ____. Antes passar 0 e tratar dentro do método mesmo então. rs..

    Mesmo assim, valeu pessoal.  =)

    quarta-feira, 19 de janeiro de 2011 14:40
  • Estou com mesmo problema, já resolveu Guillherme?
    domingo, 27 de novembro de 2011 20:29