2010-02-12 6 views
3

데이터베이스에있는 모든 열 또는 하나의 열을 검색해야하는 웹 사이트에 검색 양식이 있습니다. 다음 저장 프로 시저가 있고 datetime에 문제가 있습니다. null이되도록 어떻게합니까?저장 프로 시저, 날짜/시간

이 문제는 저장 프로 시저와 i 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); 내가 제대로 이해하면 (P.Date LIKE.... OR @date IS NULL) 같은 것을 갖고 싶어

답변

0

당신은

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

이것은 내 저장 프로 시저에서 작동하지만 codebehind에서 할 것입니다 ... datetime에 대한 textbox가 비어있을 때 ... datetime에 대해 null을 허용하지 않습니까? –

+0

검색 버튼을 클릭하면 내 코드 숨김입니다. 그러나 날짜가 텍스트 상자에 없으면 오류가 발생합니다 .... Postit p = 새 Postit(); DateTime dt = DateTime.Parse (TextBoxDate.Text); p.SearchPostit (TextBoxMessage.Text, TextBoxWriter.Text, TextBoxMailto.Text, dt); –

+0

원래의 질문에 코드를 추가하는 것이 더 좋을 수 있으므로 눈에 띄지 않게하십시오. –

0

처럼 뭔가에 where 절을 변경할 수 있습니다. DATETIME으로 작업 할 때 LIKE 부분을 BETWEEN 또는> =/< = 구조로 대체 할 수도 있습니다. 그러나 진술서를 보면 AND U.UserName LIKE... 부분은 LEFT JOIN을 INNER JOIN으로 바꾸고 모든 LIKE가있는 전체 WHERE 절이 모두 사용자의 작업을 중단하게됩니다.

0

기본값을 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 '%'[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은 "nullable로 선언"하지 않고 실제로 필요하지 않은 기본값을 할당합니다. –

+0

프랭크 고마워, 게으른 메신저 때문에 코드를 통해 "null"값을 전달하지 않아야합니다. 나는 그저 내 물건에서 완전히 생략했다. 내 대답을 업데이트 할게. – Mauro

1

DateTime.Parse() 메서드에는 특정 형식의 날짜 문자열이 필요합니다. 비어있는 TextBox 문자열은 단지 ""이며 지적한대로 실패합니다. 대안은 TextBox 문자열이 비어있는 경우 실패하지 않는 DateTime.TryParse() 메서드를 사용하는 것입니다. 결과 DateTime 시간 객체는 기본값 즉 ie로 설정됩니다. 01-Jan-0001. 고려해야 할 또 다른 측면은 날짜 입력이 빈/비어있을 것으로 예상되는 빈도입니다.

그러나이 경우에도 값은 항상 sp에 전달됩니다.

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

당신은

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 객체 초기화 그러나 경우 :

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

는 SP가 당신이 고려하는 위의 방법을 사용하는 경우 변경해야 할 수 있습니다를 필요한 경우 01-JAN-0001 날짜.

또는 DateTime을 문자열로 sp에 전달할 수 있습니다. 이 경우 SQL DateTime 대신 varchar를 사용하고 이에 따라 sp를 변경해야합니다. 다른 주에


는 널 (NULL) 날짜 시간을 사용하여 C#에서이 약간 수정 된 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을 nullable로 설정하는 방법과 매개 변수 설정을 전달할 때 nullable로 설정할 수도 있으므로 구문 분석에 실패하면 null이됩니다. –

+0

이와 비슷한 http://stackoverflow.com/questions/192121/how-do-i-use-datetime-tryparse-with-a-nullabledatetime/192146 – Ahmad

1

를 보라.그래서 같은 것을 : 당신은 전적으로 TryParse 함수에 out 매개 변수로 사용하기 위해 비 - 널 (NULL) 날짜 시간을 필요로

DateTime parsedDateValue; 
DateTime? dateValue = null; 

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

. DbCommand 및 DbParameters 클래스를 사용하면 null DateTime이 변환됩니까? 당신을 위해 데이터베이스 null 값.

저장 프로 시저에 관해서는 무엇을 사용하려고하는지 잘 모르겠습니다. P. [Date] '%'+ @ date + '%'와 유사합니다. (@Date Is Null 또는 P. [Date] = @Date)를 사용하고 @Date가 null이 아닌 경우 P와 정확히 일치하는 값만 반환합니다. [Date]. 정밀도 때문에 .NET에서 값이 전달되는 날짜에 대한 동등 비교는 신중해야합니다 (표준 SQL Server DateTime 열은 300ms로만 나가는 반면 .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 매개 변수에서 시간 요소를 제거하는 것입니다 : 당신이 주어진 일에 모든 값을 찾기 위해 시도하는 경우에, 당신은 같은 것을 할. 주어진 날짜의 0에서 일 수를 찾은 다음 그 숫자를 날짜로 전송하면됩니다. 마찬가지로 범위의 끝 지점을 다음 날 자정으로 설정하려고합니다. 이것은 날짜가 @Date에서 자정보다 크거나 같은 모든 값을 찾고 다음 날 자정보다 적은 값을 찾습니다.