C# 存储过程,日期时间
我在一个网站上有一个搜索表单,我必须在数据库的所有或一列中进行搜索。我有以下存储过程,并且datetime有问题。我将如何允许它为空 我在存储过程和c#代码背后都有这个问题 希望你能帮助我C# 存储过程,日期时间,c#,sql,stored-procedures,C#,Sql,Stored Procedures,我在一个网站上有一个搜索表单,我必须在数据库的所有或一列中进行搜索。我有以下存储过程,并且datetime有问题。我将如何允许它为空 我在存储过程和c#代码背后都有这个问题 希望你能帮助我 ALTER PROCEDURE [dbo].[SearchPostit] ( @message varchar(1000)='', @writer varchar(50)='', @mailto varchar(100)='', @date Datetime ) AS SELECT P.Messa
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
这是我点击搜索按钮时的代码隐藏。但如果文本框中没有日期,我会收到错误消息。。。。posit p=新posit();DateTime dt=DateTime.Parse(TextBoxDate.Text);p、 SearchPostit(TextBoxMessage.Text,TextBoxWriter.Text,TextBoxMailto.Text,dt) 您可以将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如….或@Date为空)
。您可能还想用BETWEEN或>=/替换类似的部分。我将该值默认为null值,然后在where子句中处理null大小写,该子句应处理不指定日期的时间
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
DateTime.Parse()
方法需要特定格式的日期字符串。空文本框字符串只是一个“
,正如您所指出的那样,它是失败的。另一种方法是使用DateTime.TryParse()
方法,该方法在文本框字符串为空时不会失败。结果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);
如果您使用上述方法来考虑0001年1月1日的日期(如果需要),则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 parsedDateValue;
DateTime? dateValue = null;
If (DateTime.TryParse(DateTextBox.Text, out parsedDateValue)
dateValue = parsedDateValue;
(
@Date Is Null Or
( P.[Date] >= Cast(DateDiff(d, 0, @Date) As DateTime)
And
P.[Date] < Cast(DateDiff(d, 0, @Date) + 1 As DateTime)
)
)
您需要不可为空的DateTime,只作为TryParse函数的out参数使用。使用DbCommand和DbParameters类将转换空DateTime?值设置为数据库null
关于存储过程,我不确定您使用“%”+@Date++“%”之类的:p.[Date]试图实现什么。如果使用(@Date为Null或P.[Date]=@Date)且@Date不为Null,则只返回与P.[Date]完全相同的值。由于精度的原因,在从.NET传递值的日期上,必须小心进行相等比较(.NET输出到纳秒,而标准SQL Server日期时间列仅输出到300毫秒)。如果要查找给定日期的所有值,请执行以下操作:
DateTime parsedDateValue;
DateTime? dateValue = null;
If (DateTime.TryParse(DateTextBox.Text, out parsedDateValue)
dateValue = parsedDateValue;
(
@Date Is Null Or
( P.[Date] >= Cast(DateDiff(d, 0, @Date) As DateTime)
And
P.[Date] < Cast(DateDiff(d, 0, @Date) + 1 As DateTime)
)
)
(
@日期为空或
(P.[Date]>=Cast(DateDiff(d,0,@Date)作为DateTime)
及
P.[Date]
这里的想法是从传递的@Date参数中去掉time元素。您可以通过从给定日期的零开始查找天数,然后将该数字转换为一个日期来完成此操作。类似地,您希望范围的终点是第二天的午夜。这转化为查找日期大于或等于@date上午夜且小于次日午夜的所有值。null不“声明为可空”,而是为其指定一个默认值,这不是真正需要的。谢谢Frank,一定是因为我很懒,不会用代码传递“null”值。我只是在我的目标中完全忽略了它。我将更新我的答案。这在我的存储过程中有效,但在codebehind中有效吗…当datetime的文本框为空时…它不接受datetime的null?这是我单击搜索按钮时的codebehind。但如果文本框中没有日期,我会收到错误消息。。。。posit p=新posit();DateTime dt=DateTime.Parse(TextBoxDate.Text);p、 SearchPostit(TextBoxMessage.Text,TextBoxWriter.Text,TextBoxMailto.Text,dt);最好是将代码添加到原始问题中,这样它就不会被忽略。如何(在C#代码中)将datetime设置为可空,并在传递参数时将其设置为可空,以便在解析失败时为空