• [SQL]躺着也中枪的datetime类型


    写在前面

    本来这个东西,我是不想在这里总结的,今天有初学者的朋友问我了,那就不得不说说了,你肯定也踩过这样的坑,没遇到,说明你运气好,编码习惯好。那还是言归正传吧。避免你中枪,还是扫一眼这篇文章吧。

    一个例子

    测试环境:sqlserver2012,vs2013

    下面看一个简单的例子,例子非常简单,就不再写注释了。一个测试的数据表TB_UserInfo:

    一个再简单不过的表,自增的id,用户名字,注册时间,从上图你也看到了,是允许为空的。

    再弄一个简单的测试程序。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Data;
     7 using System.Data.SqlClient;
     8 namespace Wolfy.SQLDateTimeDemo
     9 {
    10     class Program
    11     {
    12         static void Main(string[] args)
    13         {
    14             string strConn = "server=.;database=test;uid=sa;pwd=sa;";
    15             string strSql = "insert into TB_userInfo values(@Name,@RegDateTime)";
    16             UserInfo user = new UserInfo() { Name = "wolfy" };
    17             try
    18             {
    19                 using (SqlConnection conn = new SqlConnection(strConn))
    20                 {
    21                     using (SqlCommand cmd = new SqlCommand(strSql, conn))
    22                     {
    23                         cmd.Parameters.Add(new SqlParameter("@Name", user.Name));
    24                         cmd.Parameters.Add(new SqlParameter("@RegDateTime", user.RegDateTime));
    25                         conn.Open();
    26                         if (cmd.ExecuteNonQuery() > 0)
    27                         {
    28                             Console.WriteLine("注册成功");
    29                         }
    30                         else
    31                         {
    32                             Console.WriteLine("注册失败");
    33                         }
    34                     }
    35                 }
    36             }
    37             catch (Exception ex)
    38             {
    39                 throw ex;
    40             }
    41         }
    42     }
    43     /// <summary>
    44     /// 用户信息类
    45     /// </summary>
    46     class UserInfo
    47     {
    48         /// <summary>
    49         /// 编号
    50         /// </summary>
    51         public int Id { set; get; }
    52         /// <summary>
    53         /// 姓名
    54         /// </summary>
    55         public string Name { set; get; }
    56         /// <summary>
    57         /// 注册时间
    58         /// </summary>
    59         public DateTime RegDateTime { set; get; }
    60     }
    61 }

    我们知道,如果在使用类的属性的时候,你不为他赋值,则采用默认值。

    可见它是有默认值的。

    那我们继续往下走,再看看

    出现了,这个异常,想必很多人都遇到过吧。

    可以看出,vs中datetime类型的默认值与sqlserver中的datetime类型范围的确存在冲突。突然有这样的想法,为什么这两种默认值不兼容呢?考虑到现在的软件都会和数据库相结合,这样设计是不是有点不合理了?这东西,咱也是无法改变了,也只能选择接收了。尽量做到规范设计吧。

    有两种做法可以解决这个问题:

    方案一:

    在添加数据的时候,为datetime类型的值赋值为当前时间。

    1   UserInfo user = new UserInfo() { Name = "wolfy", RegDateTime=DateTime.Now };

    方案二:

    创建数据表的时候给时间类型的字段添加默认值约束

    1 语法:
    2 ALTER TABLE table_name
    3 ADD CONSTRAINT constraint_name
    4 DEFAULT constant_expression [FOR column_name]
    5 参数说明:
    6  table_name:要创建默认约束的表名称。
    7  constraint_name:默认约束名称。
    8  constant_expression:默认值。
    1 alter table tb_userinfo add constraint default_RegDateTime default getdate() for [RegDateTime]

     这种做法比较保险。推荐!

    总结

    这个知识点再容易不过了,估计很多初学者都会踩这样的坑,不过还好,踩过了就长记性了,也是有好处的。为什么会有这样的问题?可能你对伙伴比较信任,潜意识觉得他肯定会在数据库中添加默认约束的。到最后中枪的还是自己。所以在设计程序,编写代码的时候,一定要严谨!

  • 相关阅读:
    docker
    SAML(Security assertion markUp language) 安全断言标记语言
    kafka消息系统
    OBS 对象存储技术学习
    AOP之AspectJ
    sql查漏补缺
    todolist
    springboot 注解整理
    前端之jQuery
    前端之BOM和DOM
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/4234884.html
Copyright © 2020-2023  润新知