【问题标题】:Inserting a DateTime with SQL (while converting to string)使用 SQL 插入 DateTime(转换为字符串时)
【发布时间】:2014-11-02 20:17:26
【问题描述】:

所以基本上我使用 2 层,第一层称为“BL”(代表业务逻辑),另一层称为“DAL”。
我有一个数据库,其中包含一个用户表(在它的一个表中)。

BL 正在通过引用 (.dll) 访问 DAL,而 DAL 正在访问数据库(BL 无法直接访问数据库)。

我想在 BL 上接收用户信息,将其发送到 DAL,DAL 会将其插入数据库。

我目前的方法:

BL:

 public bool InsertUser(string userFName, string userLName, string userPass, DateTime userBirth, string userEmail, string userCountry)
    {
        if (UsersDAL.Insert(userFName, userLName, userPass, userBirth.ToString(), userEmail, userCountry))
        {
            return true;
        }
        return false;
    }

DAL:

public static bool Insert(string userFName, string userLName, string userPass, string userBirth, string userEmail, string userCountry)
    {
        DateTime userBirthday = DateTime.Parse(userBirth);
        try
        {
            OleDbHelper.fill("INSERT INTO UsersTable(userFName, userLName, userPass, userBirth, userEmail, userCountry, userActive) VALUES('" + userFName + "', '" + userLName + "', '" + userPass + "', " + userBirthday + ", '" + userEmail + "', '" + userCountry + "', true)", "UsersTable");
        }
        catch
        {
            return false;
        }
        return true;
    }

问题出现在日期时间的事情上,所以我找不到任何解决方案。

注意:在数据库中,“userBirth”是一个日期时间

【问题讨论】:

  • 啊! Sql 注入啊。 Aldo:不要将日期时间 a 视为字符串
  • 什么问题?另外,为什么要将DateTime 转换为String 只是为了在下一个方法中将其转换回DateTime?使用上面提到的 sql 参数。
  • 当你去尝试寻找即将到来的生日的人时,你会后悔没有留下DateTime thingy
  • 您确实需要参数化该查询。它不仅可以解决 DateTime 问题,还可以帮助保护您免受 SQL 注入攻击,甚至可以通过允许重用 SQL 执行计划来提高性能。

标签: c# mysql datetime


【解决方案1】:

在您的业务层中,不要使用ToString()DateTime 值转换为string

public bool InsertUser(string userFName, string userLName, string userPass, DateTime userBirth, string userEmail, string userCountry)
{
    if (UsersDAL.Insert(userFName, userLName, userPass, userBirth, userEmail, userCountry))
    {
        return true;
    }
    return false;
}

现在在您的数据访问层中,使用DateTime 代替string 作为该参数。现在DateTime userBirthday = ... 行是多余的:

public static bool Insert(string userFName, string userLName, string userPass, DateTime userBirth, string userEmail, string userCountry)
{
    try
    {
        OleDbHelper.fill("INSERT INTO UsersTable(userFName, userLName, userPass, userBirth, userEmail, userCountry, userActive) VALUES('" + userFName + "', '" + userLName + "', '" + userPass + "', " + userBirth + ", '" + userEmail + "', '" + userCountry + "', true)", "UsersTable");
    }
    catch
    {
        return false;
    }
    return true;
}

作为旁注,您应该modify your SQL command to use parameters。使用您当前的字符串连接方法,您很容易受到 SQL 注入的影响。

【讨论】:

  • 你的旁注是什么意思?请举个例子。
  • @Plutonix 它给了我一个很好的笑声,但我还没有理解这与我的项目有什么关系,如果你能举一个原始的例子,我会感谢你。
  • @BlackRainz 如果有人将 SQL 语法输入到名称中(在该示例中为 Robert'); DROP TABLE STUDENTS; --)并且您忘记对其进行清理,那么您将在连接时执行该命令。 '); 结束您当前的命令,-- 将命令的其余部分变成注释。
【解决方案2】:

我相信您正在尝试将字符串插入数据库中的日期。您应该能够将字符串转换为适合数据库中日期格式的日期(甚至可以删除 userBirth 上的 .toString() 方法并将 Insert 方法中的 userBirth 类型更改为 DateTime)。

编辑:试试这个,而不是在查询中间添加日期时间作为字符串:

SqlCommand cmd = new SqlCommand("INSERT INTO <table> (<column>) VALUES (@value)", connection);
cmd.Parameters.AddWithValue("@value", dateTimeVariable);

【讨论】:

    【解决方案3】:

    基本上,这里的根本问题是首先将日期时间视为字符串。这是不必要的,除了极少数情况下。更重要的问题是将值连接到 SQL 中的一般做法,由于各种原因,这是不好的。其中一个原因 - 实际上是较小的原因之一 - 是数字和日期格式的问题。

    基本上:使用sql参数。通过将值添加为参数而不是连接字符串,它可以正常工作。你也不会被打得那么惨。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-05
      相关资源
      最近更新 更多