2010-02-12 85 views
3

我有一个搜索表单在一个网站,我必须做所有或一列到数据库的搜索。我有以下存储过程,并有日期时间的问题。我将如何做,让它为空?存储过程,日期时间

我在存储过程和我codebehind c#中都存在这个问题。

希望你能帮助我!

ALTER PROCEDURE [dbo].[SearchPostit] ( 
@message varchar(1000)='', 
@writer varchar(50)='', 
@mailto varchar(100)='', 
@date Datetime) AS 
SELECT P.Message AS Postit, 
     P.Mailto AS 'Mailad till', 
     P.[Date] AS Datum , 
     U.UserName AS Användare 
FROM PostIt P LEFT OUTER JOIN 
    [User] U ON P.UserId=U.UserId 

WHERE P.message LIKE '%'[email protected]+'%' AND P.Mailto LIKE '%'[email protected]+'%' 
AND P.Date LIKE '%'[email protected]+'%' AND U.UserName LIKE '%'[email protected]+'%' 
GROUP BY P.Message, P.Mailto, P.[Date], U.UserName 

这是我点击搜索按钮时的代码隐藏。但是,如果在文本框中没有日期,我得到了errormessage .... Postit p = new Postit(); DateTime dt = DateTime.Parse(TextBoxDate.Text); p.SearchPostit(TextBoxMessage.Text,TextBoxWriter.Text,TextBoxMailto.Text,dt);

回答

0

你可以你的where子句更改为类似

WHERE P.message LIKE '%'[email protected]+'%' 
AND  P.Mailto LIKE '%'[email protected]+'%' 
AND  (
       @date IS NULL 
      OR P.Date = @date 
     ) 
AND  U.UserName LIKE '%'[email protected]+'%' 
+0

这适用于我的存储过程,但我会在代码隐藏....当日期时间的文本框是空的...它不接受null日期时间? – 2010-02-12 08:30:45

+0

这是我点击搜索按钮时隐藏的代码。但是,如果在文本框中没有日期,我会收到errormessage .... Postit p = new Postit(); DateTime dt = DateTime.Parse(TextBoxDate.Text); p.SearchPostit(TextBoxMessage.Text,TextBoxWriter.Text,TextBoxMailto.Text,dt); – 2010-02-12 08:35:24

+0

可能会更好地将代码添加到您的原始问题,以便它不会被忽视。 – 2010-02-12 08:38:34

0

如果我理解你正确地你想拥有像(P.Date LIKE.... OR @date IS NULL)。在使用DATETIME时,您可能还想用BETWEEN或> =/< =结构替换LIKE部分。 但是,看看你的陈述部分AND U.UserName LIKE...将左加入变成了一个INNER JOIN,并且所有LIKE的整个WHERE子句将会完全杀死你的表现。

0

我默认值为空值,然后处理where子句中的空例,然后应该处理不指定日期的时间。

ALTER PROCEDURE [dbo].[SearchPostit] (
@message varchar(1000)='', 
@writer varchar(50)='', 
@mailto varchar(100)='', 
@date Datetime = null) AS 
SELECT P.Message AS Postit, 
     P.Mailto AS 'Mailad till', 
     P.[Date] AS Datum , 
     U.UserName AS Användare 
FROM PostIt P LEFT OUTER JOIN 
    [User] U ON P.UserId=U.UserId 

WHERE 
     P.message LIKE '%'[email protected]+'%' AND 
     P.Mailto LIKE '%'[email protected]+'%' AND 
     ((@date is null) or (P.Date LIKE '%'[email protected]+'%')) AND 
     U.UserName LIKE '%'[email protected]+'%' 
GROUP BY P.Message, P.Mailto, P.[Date], U.UserName 
+0

= null不会将其“声明为可为空”,而是将其指定为默认值,这并不是真的需要。 – 2010-02-12 08:13:16

+0

谢谢弗兰克,一定是因为我懒惰,不通过代码传递一个“空值”。我只是完全在我的对象中省略它。我会更新我的答案。 – Mauro 2010-02-12 08:21:25

1

DateTime.Parse()方法需要特定格式的日期字符串。一个空的TextBox字符串只是一个"",正如你指出的那样。另一种方法是使用DateTime.TryParse()方法,该方法在TextBox字符串为空的情况下不会失败。生成的DateTime时间对象将被设置为默认值,即。 01-Jan-0001。另一个需要考虑的方面是您希望日期输入空白/空白的频率。

但是,在这种情况下,一个值将总是传递给sp。

DateTime dt=DateTime.Parse(TextBoxDate.Text) // fails if text is empty 

不过,如果你初始化的DateTime对象第一

DateTime dt = new DateTime(); 
dt = DateTime.Parse(TextBoxDate.Text) // would fail if text is empty 
DateTime.TryParse(TextBoxDate.Text, out dt) // would NOT fail if text is empty string 

使用此代码背后:

DateTime dt; 
DateTime.TryParse(TextBoxDate.Text, out dt); 

的SP可能需要的,如果你用上面的方法来考虑改变01-JAN-0001日期,如果你需要的话。

或者,您可能希望将DateTime作为字符串传递给sp。这将要求您接受varchar而不是SQL DateTime并相应地更改sp。


在不同的音符看看这个稍微返工SP

 ALTER PROCEDURE [dbo].[SearchPostit] ( 
@message varchar(1000), 
@writer varchar(50), 
@mailto varchar(100), 
@date Datetime) AS 

DECLARE @msg varchar(1002) 
DECLARE @wrt varchar(52) 
DECLARE @mlt varchar(102) 
DECLARE @dte DateTime 

IF (@message IS NULL) 
BEGIN 
    SET @msg = null 
END 
ELSE 
    SET @msg = "%"[email protected]+"%" 

    -- similar for mailto, writer values, there is probaby a cleaner way to do this though 

IF (@date is not null) 
BEGIN 
    SET @ dte = CONVERT(Datetime, @date, 101) 
END 



SELECT P.Message AS Postit, 
     P.Mailto AS "Mailad till", 
     P.[Date] AS Datum , 
     U.UserName AS Användare 
FROM PostIt P 
LEFT OUTER JOIN 
    [User] U ON P.UserId=U.UserId 
WHERE 
    P.message LIKE COALESCE(@msg, P.Message) AND 
    P.Mailto LIKE COALESCE(@lt, P.Mailto) AND 
    P.Date  LIKE @date      AND 
    U.UserName LIKE COALESCE(@wrt, P.UserName) 
GROUP BY P.Message, P.Mailto, P.[Date], U.UserName 
+0

如何(在C#代码中)将datetime设置为空,并且在传递参数时也将它设置为空,所以当解析失败时,您的空值为null。 – 2010-02-17 10:36:47

+0

像这样的东西http://stackoverflow.com/questions/192121/how-do-i-use-datetime-tryparse-with-a-nullabledatetime/192146 – Ahmad 2010-02-17 11:27:28

1

在C#中,使用可空的DateTime。因此类似于:

DateTime parsedDateValue; 
DateTime? dateValue = null; 

If (DateTime.TryParse(DateTextBox.Text, out parsedDateValue) 
    dateValue = parsedDateValue; 

您需要非空的DateTime仅用作TryParse函数的out参数。使用DbCommand和DbParameters类将转换一个空的DateTime?值为一个数据库null为你。

关于存储过程,我不确定你想要使用什么:P. [Date] Like'%'+ @ date +'%'。如果您使用(@Date Is Null或P. [Date] = @Date)并且@Date不为空,那么您将只返回完全等于P. [Date]的值。由于精度(.NET出去的时间为毫微秒,而标准的SQL Server DateTime列仅出300毫秒),因此在.NET中传递值的日期必须小心等待比较。如果你正试图找到在某一天的所有值,你这样做:

( 
@Date Is Null Or 
    (P.[Date] >= Cast(DateDiff(d, 0, @Date) As DateTime) 
    And 
    P.[Date] < Cast(DateDiff(d, 0, @Date) + 1 As DateTime) 
    ) 
) 

这里的想法是要剥去传递@date参数的时间元素。您可以通过查找给定日期从零开始的天数,然后将该数字转换为日期。同样,你希望你的范围的终点在第二天是午夜。这可以转换为查找日期大于或等于@Date午夜的所有值,并减去第二天的午夜。