2010-02-12 80 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午夜的所有值,並減去第二天的午夜。