Pular para o conteúdo principal

Inserindo valores nulos em campo DateTime - Sql Server

Com a chegada da plataforma .NET, rapidamente novos recursos foram sendo disponibilizados aliados com a facilidade de desenvolvimento de programas para esta plataforma. Cedo ou tarde os programas “legados” que são aqueles que estão a anos sendo executandos dentro das empresas, acabam sendo atualizados para uma versão mais nova usando o .NET.

Esta plataforma, atualmente na versão 4.0, traz muitas vantagens para aqueles que a adotam e sem dúvida aquelas aplicações escritas para o MS-DOS em Clipper, Dataflex ou outras, acabam precisando que seus dados sejam migrados para algum banco de dados como o Sql Server ou outro.

Numa destas converões deparei-me com um problema aparentemente simples de ser resolvido, mas, que se revelou um pouco complicado: a inserção de valores nulos em campos do Sql Server.

Se o campo em questão for do tipo string tais como VarChar, Text, etc., isto fica fácil pois podemos passar um valor ou uma string vazia para este e tudo bem, mas, se estivermos trabalhando com campos do tipo DateTime pode ficar um pouco complicado.

Estou colocando aqui uma solução para o caso de você precisar fazer uma inserção de dados em tabelas do Sql Server usando C# e ADO.NET.

Considere por exemplo a seguinte classe que vai ler os dados de uma tabela do dBase/Clipper:

Listagem 1 – Definindo os campos da classe

public class ConverteDebitos
{
	public int ID { get; set; }
	public int Parcela { get; set; }
	public DateTime Emissao { get; set; }
	public DateTime Vencimento { get; set; }
	public decimal Valor { get; set; }
	public DateTime? DataLiquidacao { get; set; }
	public decimal ValorLiquidado { get; set; }
	public decimal Juros { get; set; }
	public decimal Descontos { get; set; }

	public ConverteDebitos()
	{
	}

	public void LerDadosClipper()
	{
		/// ... algum código aqui ...
	}
Estou resumindo bem a classe para evitar entrar em detalhes que não vêm ao caso agora como por exemplo a leitura dos dados da tabela do Clipper.
Esta classe procura demonstrar um caso muito comum onde, eventualmente teremos dados do tipo DateTime nulos como no caso da propriedade “DataLiquidacao”. No caso do registro do débito ainda não ter sido liquidado, este campo estará nulo e sua migração para o Sql Server deverá manter este campo assim.
Para incluir um valor nulo num campo DateTime não adianta usarmos simplesmente o valor Null do C# nem mesmo DbNull.Value. Isto irá gerar erro na execução do programa. o valor nulo para DateTime é definido como demonstra o código abaixo:
sqlCmdInsere.Parameters.Add("@DataPagto", SqlDbType.DateTime).Value = SqlDateTime.Null;
Para poder usar este código, é necessário acrescentar o seguinte "using" no programa:
using System.Data.SqlTypes;
Terminando, veja abaixo como deve ficar um método para fazer a inclusão dos dados na tabela SqlServer. Para isso funcionar, devem ser inserindos os seguintes usings:
using System.Data;
using System.Data.SqlClient;
Lista 2 – Método para inserção dos dados
	
public bool InsereRegistro(out string erro)
{
	// Define a conexao com o banco
	using (SqlConnection sqlConn = new SqlConnection("...informe sua string de conexao aqui..."))
	{
		using (SqlCommand sqlCmdInsere = new SqlCommand())
		{
			try
			{
				erro = "";
				// Define o comando que insere os dados
				sqlCmdInsere.Connection = sqlConn;
				sqlCmdInsere.CommandText = @"
				insert into debito
				(
					Id,
					Parcela,
					Emissao,
					Vencimento,
					Valor,
					DataPagto,
					ValorRecebido,
					Juros,
					Desconto
				)
				values
				(
					@Id,
					@Parcela,
					@Emissao,
					@Vencimento,
					@Valor,
					@DataPagto,
					@ValorRecebido,
					@Juros,
					@Desconto
				)";

				// inclui os parâmetros
				sqlCmdInsere.Parameters.Add("@ID", SqlDbType.Int).Value = this.ID;
				sqlCmdInsere.Parameters.Add("@Parcela", SqlDbType.Int).Value = this.Parcela;
				sqlCmdInsere.Parameters.Add("@Emissao", SqlDbType.DateTime).Value = this.Emissao;
				sqlCmdInsere.Parameters.Add("@Vencimento", SqlDbType.DateTime).Value = this.Vencimento;
				sqlCmdInsere.Parameters.Add("@Valor", SqlDbType.Decimal).Value = this.Valor;

				// neste ponto, verifica se existem algum valor no campo
				if (this.DataLiquidacao.HasValue)
				{
					sqlCmdInsere.Parameters.Add("@DataPagto", SqlDbType.DateTime).Value =
						this.DataLiquidacao.HasValue;
				}
				else
				{
					// passa valor nulo para a tabela
					sqlCmdInsere.Parameters.Add("@DataPagto", SqlDbType.DateTime).Value = SqlDateTime.Null;
				}

				sqlCmdInsere.Parameters.Add("@ValorRecebido", SqlDbType.Decimal).Value = this.ValorLiquidado;
				sqlCmdInsere.Parameters.Add("@Juros", SqlDbType.Decimal).Value = this.Juros;
				sqlCmdInsere.Parameters.Add("@Desconto", SqlDbType.Decimal).Value = this.Descontos;

				sqlConn.Open();
				sqlCmdInsere.ExecuteNonQuery();
				return true;
			}
			catch (Exception ex)
			{
				// faz tratamento de erros do código
				erro = ex.Message;
			}
			finally
			{
				if (sqlConn.State == ConnectionState.Open)
				{
					sqlConn.Close();
				}
			}

			return false;
		}
	}
}
No código acrescentei algum tratamento de erro que uso por padrão. Você pode optar por fazer isto de maneiras diferentes.
Procure explorar o namespace SqlTypes que possui ainda os seguintes tipos:
  • SqlBinary.
  • SqlBoolean.
  • SqlByte.
  • SqlDecimal.
  • SqlDouble.
  • SqlGuid.
  • SqlInt16.
  • SqlInt32.
  • SqlInt64.
  • SqlMoney.
  • SqlSingle.
  • SqlString.
  • SqlXml.
Todos estes tipos permitindo incluir valores nulos no banco de dados.
Por enquanto é isso, espero que tenha ajudado. Abraços.

Postagens mais visitadas deste blog

Como gerar scripts para exportar dados no SQL Server 2008

Uma das tarefas mais comuns no trabalho com desenvolvimento de software que consome dados em bancos como o SQL Server 2008 é a necessidade de em algum momento precisarmos exportar os dados de um banco para outro. Quer seja para realizar testes ou fazer simulações existem várias maneiras de se fazer isto. Neste post eu quero demonstrar um recurso do SQL Server Management Studio (SSMS) que permite realizar esta tarefa rapidamente.Para os que estão acostumados a usar esta ferramenta, já devem saber que é possível gerar scripts para o schema e também transferir os dados entre dois bancos distintos. Isto pode ser feito se o SSMS puder conectar-se com as duas bases, de origem e destino. No exemplo que vou dar, o objetivo é gerar o script apenas para uma tabela do banco de dados de exemplo da Microsoft – Northwind.1. Iniciando o assistenteO assistente deve ser iniciado clicando com o botão direito do mouse sobre o banco onde se encontra a tabela a qual iremos gerar o script. Deve se clicar n…

Pivot dinâmico com SQL Server

Passo a passo para usar pivoteamento dinâmicoOs bancos de dados bem configurados e definidos armazenam os dados de forma a otimizar o acesso, evitando duplicidade e garantindo a integridade. Porém, em muitas situações isto pode dificultar a apresentação de forma adequada sendo necessário preparar os dados usando vários recursos entre os quais, fazer o pivoteamento.Se você não precisou ainda usar ou não sabe o que é consiste em transformar cada linha de uma determinada coluna em colunas de uma nova consulta.Assim, considere uma tabela que armazene as notas bimestrais de um boletim. Uma possível estrutura para esta tabela seria algo assim:ColunaTipo de dado/TamanhoDisciplinanvarchar(50)BimestreIntNotanumeric(5,2)Uma consulta select nesta tabela com alguns dados traria um resultado parecido com o abaixo:Porém pode ser que para apresentar estes dados em um relatório seja necessário transformar cada bimestre em uma coluna e agrupar as notas nestas colunas para que fique dessa forma:Isto po…

Desabilitando o auto commit no SSMS (SQL Server Management Studio)

(Ou, como prevenir desastres e manter o emprego a salvo…)Neste post vai uma pequena mas tremendamente útil dica para desabilitar o auto commit da aplicação SQL Server Management Studio (SSMS) que é usada por dez entre dez usuários do banco de dados SQL Server para fazer consultas, alterações e executar scripts no banco de dados. (Preferências à parte, realmente muita gente usa),A primeira e mais importante notícia é que, diferentemente da ferramenta do Oracle, este editor de scripts do SQL Server vem com o recurso de auto commit ativado por padrão, assim, qualquer instrução DML (alteração dos dados com update, insert e delete) ou DDL (alteração no banco como create, drop, alter, etc.) será imediatamente enviada ao banco e persistida.Isto pode ser altamente crítico pois se estiver executando as instruções em um banco de dados de produção não haverá muitas formas de desfazer se é que haverá.Inicialmente, pode se evitar muitos acidades executando estas instruções dentro de um bloco BEGIN…