1

我正在尝试针对 Sqlite 数据库实现数据访问层。我的一张表包含一个日期时间字段。

我在将数据插入此日期时间字段时遇到问题。

cmd.CommandText = string.Format(
                        "INSERT INTO Orders(" +
                            "OrderId, " +
                            "Status, " +
                            "CreationTime, " +
                            "LastModification, " +
                            "CreatorName) " +
                        "VALUES(@orderId,@status,@creation,@modification,@creator)";
                    cmd.Parameters.AddWithValue("@orderId", orderId);
                    cmd.Parameters.AddWithValue("@status", status);
                    cmd.Parameters.AddWithValue("@creation", creationTime);
                    cmd.Parameters.AddWithValue("@modification", lastModificationTime);
                    cmd.Parameters.AddWithValue("@creator", creatorName);

我的表创建:

cmd.CommandText = "CREATE TABLE IF NOT EXISTS Orders(" +
                                  "OrderId TEXT PRIMARY KEY NOT NULL, " +
                                  "Status TEXT, " +
                                  "CreationTime DATETIME, " +
                                  "LastModification DATETIME, " +
                                  "CreatorName TEXT)";
4

1 回答 1

3

不要手动创建字符串,而是使用参数化查询并添加参数值。正如您所发现的,使用 String.Format 肯定会导致转换错误,并使您面临 SQL 注入攻击。

当您使用参数时,值会在没有任何转换的情况下传递,因此您永远不必担心转换错误或注入攻击。当大多数数据库知道哪些部分可以更改以及哪些部分从一次执行到下一次执行时保持不变时,它们也能够更好地优化查询。

在你的情况下,你可以使用这样的东西:

cmd.CommandText= "INSERT INTO Orders(" +
                        "OrderId, " +
                        "Status, " +
                        "CreationTime, " +
                        "LastModification, " +
                        "CreatorName) " +
                    "VALUES (@orderId,@status,@creation,@modification,@creator)";
cmd.Parameters.AddWithValue("@orderId",orderId);
cmd.Parameters.AddWithValue("@status",status);
cmd.Parameters.AddWithValue("@creation",creation);
cmd.Parameters.AddWithValue("@modification",modification);
cmd.Parameters.AddWithValue("@creator",creator);

题外话 - 为什么参数化查询更快

所有服务器都必须解析查询以了解其结构并创建执行计划来运行查询。该计划包含要使用的索引、过滤或加入的策略、可能需要的临时结构等。创建此计划的成本很高,因此大多数服务器会缓存他们创建的计划以供以后使用。

除非服务器知道查询中的哪些值实际上是参数以及哪些是手动编码的,否则它无法决定是否可以使用现有计划或创建新计划,而无需实际解析查询。通过自己指定参数,您可以让服务器创建更好且可重用的计划。如果您每秒执行大量查询,这可能是一个显着的提升。

更不用说以原生形式传递值比作为文本传递更轻,因此也更快。

于 2013-10-10T13:25:20.327 回答