使用 DateTime 时 INSERT INTO 语句中的语法错误

Posted

技术标签:

【中文标题】使用 DateTime 时 INSERT INTO 语句中的语法错误【英文标题】:Syntax error in INSERT INTO statement while using DateTime 【发布时间】:2012-04-27 15:33:44 【问题描述】:

我在 Insert INTO 语句中收到“语法错误,但我不知道原因。

我将该陈述与我所做的工作发现的其他陈述进行了比较,并没有发现结构上的差异。唯一的区别是,在这一个中,我试图在我的 MS Access 数据库中保存一个 DateTime。

我在 MS Access 中为日期/时间设置了我的数据库字段,格式为 MM/DD/YY HH:MM:SS AM(或 PM)。我的 DateTime 格式设置相同。

当我设置一个断点并执行它时,我可以看到传递的 DateTime 格式是正确的,并且与 MS Access 中的一般格式相匹配。

我确定问题出在我自己身上,但如果我能看到它,我会很生气。这是我的代码:

//method to save user input to database
public static void SaveData(ProgramLoginBOL busObject)

    try
    
        String sSQLCommand = "INSERT INTO ProgramLogin ( " +
            "UserName, DateTime) VALUES ('" + busObject.UserName + 
            "','" + busObject.DtDate + "')";

        if (aConnection.State == ConnectionState.Closed)
        
            aConnection.Open();
        

        OleDbCommand cmd = aConnection.CreateCommand();
        cmd.CommandText = sSQLCommand;
        // Execute the SQL command
        cmd.ExecuteNonQuery();
        aConnection.Close();

        MessageBox.Show("Data Saved");                 
    
    catch (Exception ex)
    
        Console.WriteLine(ex.ToString());
        MessageBox.Show("Error! Data was not saved.");
    

正如我所说,调试表明 busObject.DtDate 与 MS Access 日期/时间格式匹配

【问题讨论】:

你有一个 SQL 注入漏洞。你需要使用参数。 感谢您的帮助。 【参考方案1】:

解决问题的一种方法是改用参数化查询。这样做会让提供商担心类型,您不必担心用单引号分隔字符串值(有助于使用 O'Donnel 之类的名称)或用 # 为值加上日期。作为奖励,它避免了任何 SQL 注入攻击。

要这样做吗?参数占位符

   string sSQLCommand = "INSERT INTO ProgramLogin ( " +
            "UserName, DateTime) VALUES (?,?)" 

然后再添加参数

   cmd.Parameters.AddWithValue("?", busObject.UserName);
   cmd.Parameters.AddWithValue("?", busObject.DtDate);

【讨论】:

虽然这不是家庭作业,但我使用我的学校教科书作为指导来创建我的程序,它没有显示任何类似的内容。为了保护张贴者所说的“SQL注入漏洞”,所有数据库插入是否应该这样做? @ProgrammingNewbie。使用参数化查询是保护自己免受 SQL 注入攻击的一种方法。使用 Access,您可以使用带有参数的查询定义来完成此操作。对于其他数据库,您可以改用存储过程。当然,如果您完全信任这些价值观,那么问题就不大了【参考方案2】:

对于 Access,您必须用 # 字符将日期括起来。

因此,将您的命令更改为:

String sSQLCommand = "INSERT INTO ProgramLogin (UserName, DateTime) VALUES ('" + busObject.UserName + "',#" + busObject.DtDate + "#)"; 

像这样格式化您的日期字符串以获得最佳效果:

#2012-04-21 13:21:25#

【讨论】:

【参考方案3】:

您分配给访问日期/时间列的显示格式与查询中日期/时间值的正确字符串格式无关。

您可以在 DateTime 值上调用适当的 ToString 重载,以按照 Access 的要求对其进行格式化,或者,正如 SLaks 所评论的那样,您可以使用参数。使用参数更安全,这也意味着您无需担心值的格式。 OleDb 提供商会为您处理好这些。

【讨论】:

非常感谢您的帮助。我认为格式必须匹配。由于使用参数更安全,所以我将使用它。

以上是关于使用 DateTime 时 INSERT INTO 语句中的语法错误的主要内容,如果未能解决你的问题,请参考以下文章

怎么向sqlserver插入datetime 格式数据

insert into的用法

调用 OPENROWSET 时 INSERT INTO 和 SELECT INTO 的区别

使用此 INSERT INTO 语句和 .NET OleDb 命名空间时如何解决语法错误?

访问 INSERT INTO - 几个参数。预计 2

INSERT INTO SELECT 很慢,但是单独运行时 INSERT 或 SELECT 很快