Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 参数化查询和空DateTime值_C#_Sql_Ms Access_Ms Access 2007 - Fatal编程技术网

C# 参数化查询和空DateTime值

C# 参数化查询和空DateTime值,c#,sql,ms-access,ms-access-2007,C#,Sql,Ms Access,Ms Access 2007,我正在使用一个程序,从access数据库中提取一个字符串字段,从日期中分离出一个名称(第一个和最后一个),然后将该名称与另一个access数据库中的日期分开保存 我已经完成了所有的工作,除了一些日期值为空,所以我需要对SQL进行参数化,但我还没有弄清楚如何使参数化工作 我已经为变量输入了虚拟值,它将它们添加到表中。我在下面的代码片段中删去了其他变量,因为它们都是重复的。os是一个保存结构中数据的列表 string sqlcmd = "INSERT INTO signatures VALUES (

我正在使用一个程序,从access数据库中提取一个字符串字段,从日期中分离出一个名称(第一个和最后一个),然后将该名称与另一个access数据库中的日期分开保存

我已经完成了所有的工作,除了一些日期值为空,所以我需要对SQL进行参数化,但我还没有弄清楚如何使参数化工作

我已经为变量输入了虚拟值,它将它们添加到表中。我在下面的代码片段中删去了其他变量,因为它们都是重复的。os是一个保存结构中数据的列表

string sqlcmd = "INSERT INTO signatures VALUES ('" + os.QASignature + "', 'QADate = @QADATE'";
System.Data.OleDb.OleDbCommand SQLCommand = new System.Data.OleDb.OleDbCommand(sqlcmd, Connection);
using (SQLCommand)
{
    SQLCommand.Parameters.Add("@QADATE", System.Data.OleDb.OleDbType.Date).Value = os.QADate;
    SQLDataReader = SQLCommand.ExecuteReader();
}
您需要将
null
转换为。实现这一点的一种方法是,假设QADate是一个可为空的DateTime(那么DateTime?),可以是:

... .Value = os.QADate ?? DBNull.Value;
???是的

编辑:您可能实际上需要强制转换以确保两个操作数的类型相同:

... .Value = (object)os.QADate ?? DBNull.Value;
还有,为什么不为QASignature使用参数??为什么要“内联”这个值?我不知道QASignature会包含什么,但这会让你容易受到攻击

最后,为什么要使用插入?为什么不使用?

您需要将
null
转换为。实现这一点的一种方法是,假设QADate是一个可为空的DateTime(那么DateTime?),可以是:

... .Value = os.QADate ?? DBNull.Value;
???是的

编辑:您可能实际上需要强制转换以确保两个操作数的类型相同:

... .Value = (object)os.QADate ?? DBNull.Value;
还有,为什么不为QASignature使用参数??为什么要“内联”这个值?我不知道QASignature会包含什么,但这会让你容易受到攻击

最后,为什么要使用插入?为什么不使用?

使用:

作为旁注,使用会自动推断数据类型,并允许您缩短代码:

SQLCommand.Parameters.AddWithValue("@QADATE", DBNull.Value);
使用:

作为旁注,使用会自动推断数据类型,并允许您缩短代码:

SQLCommand.Parameters.AddWithValue("@QADATE", DBNull.Value);

考虑使用该结构。然后,只有在源对象中确实存在变量时,才可以设置它。否则,该值将设置为Null,并将其自身很好地传递到SQL参数中。许多旧的TableAdapter类和更新的EntityFramework对象也可以使用Nullable(of T)结构。

考虑使用该结构。然后,只有在源对象中确实存在变量时,才可以设置它。否则,该值将设置为Null,并将其自身很好地传递到SQL参数中。许多旧的TableAdapter类和较新的EntityFramework对象也可以使用Nullable(of T)结构。

下面的内容应该是您想要的:

string sqlcmd = "INSERT INTO signatures (QASignature, QADate) VALUES (?, ?)";
using (System.Data.OleDb.OleDbCommand SQLCommand = new System.Data.OleDb.OleDbCommand(sqlcmd, Connection))
{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "QASignature", Value = os.QASignature, DbType = DbType.String});
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "QADATE", Value = os.QADate, DbType = DbType.DateTime});
    SQLCommand.ExecuteNonQuery(); //Use ExecuteReader or ExecuteScalar when you want to return something
} 
如果os.QADate可为空(
DateTime?
System.nullable
),则您将执行以下操作:

if(os.QADate == null) //Could easily be os.QADate == DateTime.MinValue too, for example
{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "@QADATE", Value = DBNull.Value, DbType = DbType.DateTime});
}
else{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "@QADATE", Value = os.QADate, DbType = DbType.DateTime});
}
请注意,您不应该像在原始示例中那样混合字符串连接和参数-这是一个或另一个!实际上,它应该只是参数化,以防止SQL注入,并获得其他好处(例如更容易键入,在某些RDBMS中,参数化查询的性能更好)


还要注意的是,OleDBCommand不能从命名参数中获益——参数必须按照它们在SQL中出现的顺序添加到查询中。这就是SQL查询包含两个问号的原因-它们只是占位符。

下面的内容应该是您想要的:

string sqlcmd = "INSERT INTO signatures (QASignature, QADate) VALUES (?, ?)";
using (System.Data.OleDb.OleDbCommand SQLCommand = new System.Data.OleDb.OleDbCommand(sqlcmd, Connection))
{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "QASignature", Value = os.QASignature, DbType = DbType.String});
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "QADATE", Value = os.QADate, DbType = DbType.DateTime});
    SQLCommand.ExecuteNonQuery(); //Use ExecuteReader or ExecuteScalar when you want to return something
} 
如果os.QADate可为空(
DateTime?
System.nullable
),则您将执行以下操作:

if(os.QADate == null) //Could easily be os.QADate == DateTime.MinValue too, for example
{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "@QADATE", Value = DBNull.Value, DbType = DbType.DateTime});
}
else{
    SQLCommand.Parameters.Add(new OleDbParameter() { Name = "@QADATE", Value = os.QADate, DbType = DbType.DateTime});
}
请注意,您不应该像在原始示例中那样混合字符串连接和参数-这是一个或另一个!实际上,它应该只是参数化,以防止SQL注入,并获得其他好处(例如更容易键入,在某些RDBMS中,参数化查询的性能更好)


还要注意的是,OleDBCommand不能从命名参数中获益——参数必须按照它们在SQL中出现的顺序添加到查询中。这就是SQL查询包含两个问号的原因-它们只是占位符。

DateTime不能为null,如果该值未初始化,则为DateTime.MinValue。 您需要针对这种情况进行测试,并将参数也用于字符串值

using System.Data.OleDb;
....

string sqlcmd = "INSERT INTO signatures VALUES (@QASignature, @QADATE)"; 
using(OleDbCommand SQLCommand = new OleDbCommand(sqlcmd, Connection))
{ 
    SQLCommand.Parameters.AddWithValue("@QASignature",  os.QASignature);
    SQLCommand.Parameters.Add("@QADATE", OleDbType.Date).Value = 
               (os.QADate == DateTime.MinValue 
               ? (object)DBNull.Value
               : (object)os.QADate); 
    SQLDataReader = SQLCommand.ExecuteNonQuery(); 
} 

顺便说一下,insert语句通常由
ExecuteNonQuery

执行。DateTime不能为空,如果该值未初始化,则为DateTime.MinValue。 您需要针对这种情况进行测试,并将参数也用于字符串值

using System.Data.OleDb;
....

string sqlcmd = "INSERT INTO signatures VALUES (@QASignature, @QADATE)"; 
using(OleDbCommand SQLCommand = new OleDbCommand(sqlcmd, Connection))
{ 
    SQLCommand.Parameters.AddWithValue("@QASignature",  os.QASignature);
    SQLCommand.Parameters.Add("@QADATE", OleDbType.Date).Value = 
               (os.QADate == DateTime.MinValue 
               ? (object)DBNull.Value
               : (object)os.QADate); 
    SQLDataReader = SQLCommand.ExecuteNonQuery(); 
} 

顺便说一下,insert语句通常由
ExecuteNonQuery

DateTime
执行,实际上不能为空,
DateTime?
但是,can:-)我假设后者,因为user1533116声明:“一些日期值为空。对不起,@Steve,我无意中编辑了你的帖子。已回滚到原始版本。我删除了System.Data.OleDb.OleDbCommand部分,因此没有更改它的性质。我一定是瞎了。@dash,好吧,不过你的编辑是对的。让我还原您的更改:-)我唯一的另一个评论是,您不能以这种方式设置值,因为DBNull.value和DateTime之间没有转换-不幸的是,您不能以这种方式使用三元[conditional]运算符。但是,它仍然是+1,因为您是唯一在上下文中提到DateTime.MinValue的人。@dash,对,我没有注意到这一点。但是,将强制转换添加到对象是可行的。确切地说,你的答案更好。
DateTime
确实不能为null,
DateTime?
但是,can:-)我假设后者,因为user1533116声明:“一些日期值为null”。对不起,@Steve,我无意中编辑了你的帖子。已回滚到原始版本。我删除了System.Data.OleDb.OleDbCommand部分,因此没有更改它的性质。我一定是瞎了。@dash,好吧,不过你的编辑是对的。让我还原您的更改:-)我唯一的另一个评论是,您不能以这种方式设置值,因为DBNull.value和DateTime之间没有转换-您不能使用ternar