3 Stimmen

Gespeicherte Prozedur, datetime

Ich habe ein Suchformular in einer Website, wo ich eine Suche in allen oder einer Spalte der Datenbank durchführen muss. Ich habe die folgende gespeicherte Prozedur und habe ein Problem mit datetime. Wie kann ich zulassen, dass es null ist?

Ich habe Problem mit diesem sowohl in gespeicherte Prozedur und ich codebehind c#.

Ich hoffe, Sie können mir helfen!

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

Dies ist mein Code, wenn Sie auf die Schaltfläche Suchen klicken. Aber ich habe Fehlermeldung, wenn kein Datum in Textbox.... ist Postit p = new Postit(); DateTime dt=DateTime.Parse(TextBoxDate.Text); p.SearchPostit(TextBoxMessage.Text, TextBoxWriter.Text, TextBoxMailto.Text,dt);

1voto

Ahmad Punkte 19007

El DateTime.Parse() Methode erfordert eine Datumszeichenfolge in einem bestimmten Format. Eine leere TextBox-Zeichenkette ist nur eine "" was, wie Sie sagten, nicht funktioniert. Eine Alternative wäre die Verwendung der DateTime.TryParse() Methode, die nicht fehlschlägt, wenn die TextBox-Zeichenfolge leer ist. Das resultierende DateTime-Zeitobjekt würde auf die Standardwerte gesetzt werden, d.h.. 01-Jan-0001 . Ein weiterer zu berücksichtigender Aspekt ist die Frage, wie oft die Datumseingabe leer sein soll.

In diesem Fall wird jedoch immer ein Wert an die sp übergeben.

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

Wenn Sie jedoch die Initialisierung der DateTime Objekt zuerst

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

Verwenden Sie diesen Code dahinter:

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

Wenn Sie die oben beschriebene Methode anwenden, müssen Sie möglicherweise das Datum 01-JAN-0001 berücksichtigen, wenn dies erforderlich ist.

Alternativ können Sie die DateTime auch als String an die sp übergeben. In diesem Fall müssten Sie anstelle von SQL DateTime ein varchar akzeptieren und die sp entsprechend ändern.


Schauen Sie sich auch dieses leicht überarbeitete SP an

        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

1voto

Thomas Punkte 62314

In C#, verwenden Sie eine nullable DateTime. Also etwas wie:

DateTime parsedDateValue;
DateTime? dateValue = null;

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

Sie benötigen die nicht-nullbare DateTime ausschließlich für die Verwendung als Out-Parameter für die TryParse-Funktion. Die Verwendung der Klassen DbCommand und DbParameters konvertiert einen DateTime?-Wert von Null in eine Datenbank-Null für Sie.

Was die gespeicherte Prozedur angeht, bin ich mir nicht sicher, was Sie damit erreichen wollen: P.[Datum] Like'%'+@Datum+'%'. Wenn Sie ( @Datum ist Null oder P.[Datum] = @Datum ) verwenden und @Datum ist nicht Null, dann geben Sie nur Werte zurück, die genau gleich P.[Datum] sind. Sie müssen mit Gleichheitsvergleichen bei Datumsangaben vorsichtig sein, wenn die Werte von .NET übergeben werden, weil die Genauigkeit nicht ausreicht (.NET geht bis zu Nanosekunden, während Standard-SQL Server DateTime-Spalten nur bis zu 300 ms gehen). Wenn Sie versuchen, alle Werte an einem bestimmten Tag zu finden, machen Sie etwas wie:

( 
@Date Is Null Or 
    ( P.[Date] >= Cast(DateDiff(d, 0, @Date) As DateTime)
    And 
    P.[Date] < Cast(DateDiff(d, 0, @Date) + 1 As DateTime)
    )
)

Hier geht es darum, das Zeitelement aus dem übergebenen @Date-Parameter zu entfernen. Sie können dies tun, indem Sie die Anzahl der Tage ab Null des angegebenen Datums ermitteln und diese Zahl dann in ein Datum umwandeln. In ähnlicher Weise soll der Endpunkt des Bereichs um Mitternacht des folgenden Tages liegen. Dies bedeutet, dass alle Werte gefunden werden müssen, bei denen das Datum größer oder gleich Mitternacht am @Datum und kleiner als Mitternacht am Folgetag ist.

0voto

Adriaan Stander Punkte 155899

Sie könnten Ihre Where-Klausel ändern in etwas wie

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

0voto

Frank Kalis Punkte 1302

Wenn ich Sie richtig verstehe, möchten Sie etwas haben wie (P.Date LIKE.... OR @date IS NULL) . Sie können auch den LIKE-Teil durch ein BETWEEN- oder >=/<=-Konstrukt ersetzen, wenn Sie mit DATETIMEs arbeiten. In Ihrer Anweisung ist jedoch der Teil AND U.UserName LIKE... verwandelt den LEFT JOIN in einen INNER JOIN und die ganze WHERE-Klausel mit all den LIKEs wird Ihre Leistung völlig zerstören.

0voto

Mauro Punkte 4495

Ich standardmäßig den Wert auf einen Null-Wert und behandeln dann den Null-Fall in der Where-Klausel, die dann die Zeiten, wo Sie nicht ein Datum angeben behandeln sollte.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X