[英]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.