我有一个C#控制台应用程序,该应用程序正在SQL Server 2014上执行数据库查找。它对带有名为有效日期的DateTime列的表进行查询,该列允许空值。
如果我编写使用“ WHERE EffectiveDate IS NULL”的标准SQL查询,结果将正确返回。如果我更改WHERE子句以接受参数并将该参数设置为DBNull.Value,则结果为null。
示例1使用IS NULL-> resultObj具有适当的值:
public void RetrieveFileType()
{
string sSQL = "SELECT [FileType] " +
"FROM DTCC_APP_ProcessControl " +
"WHERE [EffectiveDate] IS NULL ";
using (SqlConnection oConn = GetNewConnection())
{
using (SqlCommand cmd = new SqlCommand(sSQL, oConn))
{
object resultObj = cmd.ExecuteScalar();
}
}
}
示例2使用DBNull.Value-> resultObj = null:
public void RetrieveFileType()
{
string sSQL = "SELECT [FileType] " +
"FROM DTCC_APP_ProcessControl " +
"WHERE [EffectiveDate] = @EffectiveDate";
using (SqlConnection oConn = GetNewConnection())
{
using (SqlCommand cmd = new SqlCommand(sSQL, oConn))
{
cmd.Parameters.AddWithValue("@EffectiveDate", DBNull.Value);
object resultObj = cmd.ExecuteScalar();
}
}
}
我也尝试过:
cmd.Parameters.Add("@EffectiveDate", SqlDbType.DateTime).Value = DBNull.Value;
和
cmd.Parameters.AddWithValue("@EffectiveDate", SqlDateTime.Null);
我唯一得到结果的是是否使用IS NULL。这是一个简化的示例,我可以选择为@EffectiveDate设置一个值或Null。
我已经阅读了其他在线信息,似乎我需要的只是一个可为空的数据库列,并使用DBNull.Value作为参数,它应该可以工作。我想念什么?
答案 0 :(得分:2)
问题与参数化无关,但与参数可以具有NULL
值这一事实无关。就像 Steve 所说的那样,您不能直接将NULL
与NULL
进行比较,否则它将不会返回任何内容(根据SQL标准,它始终为false)。 / p>
当参数被保证从不为NULL
时,示例2中的直接比较效果很好,如果示例1始终为NULL
,则示例1很好。但是,如果根据某些外部条件有可能出现NULL
或不出现SELECT [FileType]
FROM DTCC_APP_ProcessControl
WHERE [EffectiveDate] = @EffectiveDate OR @EffectiveDate IS NULL
的情况,我们也必须考虑将其纳入SQL查询。这样的事情会做:
EffectiveDate
这可以同时处理两种情况,但是请注意,此表达式不可SARGable,并且如果有Sub OptimizeCode_Begin()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
ActiveSheet.DisplayPageBreaks = False
End Sub
_____
Sub OptimizeCode_End()
ActiveSheet.DisplayPageBreaks = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
______
Sub GetFromOutlook()
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim Folder As MAPIFolder
Dim OutlookMail As Variant
Dim i As Long
Dim j As Long
Call OptimizeCode_Begin
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set Folder = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("Individual Lot Inspections")
Set Folder2 = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("Construction Site Inspections")
i = 1
For Each OutlookMail In Folder.Items
If OutlookMail.ReceivedTime >= Range("From_date").Value Then
Range("eMail_subject").Offset(i, 0).Value = OutlookMail.Subject
Range("eMail_date").Offset(i, 0).Value = OutlookMail.ReceivedTime
Range("eMail_sender").Offset(i, 0).Value = OutlookMail.SenderName
' Range("eMail_text").Offset(i, 0).Value = OutlookMail.Body
i = i + 1
End If
Next OutlookMail
j = i + 1
For Each OutlookMail In Folder2.Items
If OutlookMail.ReceivedTime >= Range("From_date").Value Then
Range("eMail_subject").Offset(j, 0).Value = OutlookMail.Subject
Range("eMail_date").Offset(j, 0).Value = OutlookMail.ReceivedTime
Range("eMail_sender").Offset(j, 0).Value = OutlookMail.SenderName
j = j + 1
End If
Next OutlookMail
Set Folder = Nothing
Set Folder2 = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
Call OptimizeCode_End
列,则不会使用索引。
另一种方法是,根据参数的最终值,客户端选择动态地在示例1或2之间进行选择,以提交一个或另一个查询。这可能会导致更好的性能和索引使用率。
答案 1 :(得分:1)
因为DB中的NULL
与c#不同。
NULL = NULL
在Sql中返回false。您必须使用IS NULL
进行比较