簡體   English   中英

存儲過程,日期時間

[英]Stored procedure, datetime

我在一個網站上有一個搜索表單,我必須在全部或一列中搜索數據庫。 我有以下存儲過程,並有日期時間的問題。 如何讓它為空呢?

我在存儲過程和代碼隱藏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 '%'+@message+'%' AND P.Mailto LIKE '%'+@mailto+'%' 
AND P.Date LIKE '%'+@date+'%' AND U.UserName LIKE '%'+@writer+'%'
GROUP BY P.Message, P.Mailto, P.[Date], U.UserName

這是我點擊搜索按鈕后的代碼隱藏。 但是如果文本框中沒有日期,我會收到錯誤消息.... Postit p = new Postit(); DateTime dt = DateTime.Parse(TextBoxDate.Text); p.SearchPostit(TextBoxMessage.Text,TextBoxWriter.Text,TextBoxMailto.Text,dt);

DateTime.Parse()方法需要特定格式的日期字符串。 一個空的TextBox字符串只是一個"" ,正如你指出的那樣失敗。 另一種方法是使用DateTime.TryParse()方法,該方法在TextBox字符串為空時不會失敗。 生成的DateTime時間對象將設置為默認值ie。 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);

如果您需要,如果使用上述方法考慮01-JAN-0001日期,sp可能需要更改。

或者,您可能希望將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 = "%"+@message+"%"

    -- 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

在C#中,使用可為空的DateTime。 所以類似於:

DateTime parsedDateValue;
DateTime? dateValue = null;

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

您需要不可為空的DateTime僅用作TryParse函數的out參數。 使用DbCommand和DbParameters類將轉換null DateTime? 值為數據庫null為您。

關於存儲過程,我不確定你要使用什么來完成:P。[Date]喜歡'%'+ @ date +'%'。 如果你使用(@Date Is Null或P. [Date] = @Date)並且@Date不為null,那么你將只返回完全等於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上查找日期大於或等於午夜的所有值,並且在第二天的午夜更少。

您可以將where子句更改為類似的子句

WHERE   P.message LIKE '%'+@message+'%' 
AND     P.Mailto LIKE '%'+@mailto+'%'  
AND     (
                @date IS NULL 
            OR  P.Date = @date
        )
AND     U.UserName LIKE '%'+@writer+'%' 

如果我理解正確你想要的東西(P.Date LIKE.... OR @date IS NULL) 在使用DATETIME時,您可能還希望用BETWEEN或> = / <=構造替換LIKE部件。 但是,查看你的語句部分AND U.UserName LIKE...將LEFT JOIN轉換為INNER JOIN,並且包含所有AND U.UserName LIKE...的整個WHERE子句將完全殺死你的性能。

我將該值默認為空值,然后在where子句中處理null case,然后該子句應處理您未指定日期的時間。

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 '%'+@message+'%' AND
      P.Mailto LIKE '%'+@mailto+'%' AND
      ((@date is null) or (P.Date LIKE '%'+@date+'%')) AND
      U.UserName LIKE '%'+@writer+'%'
GROUP BY P.Message, P.Mailto, P.[Date], U.UserName

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM