parametri SQL che può essere facoltativo
Domanda
Ho questo problema in cui ho bisogno di impostare i parametri "opzionali" per il mio stored procedure per funzionare bene. Per esempio, io ho questo:
CREATE PROCEDURE [dbo].[Search]
(
@StartTime datetime = NULL,
@EndTime datetime = NULL,
@CustomerEmail nvarchar(255) = NULL,
@OrderStatusID int
)
Ora, nel mio sito .net ho questo come un esempio, si prega di tenere a mente che non ci può essere un solo parametro o ci potrebbe essere tutto di loro:
commAdvanced.Parameters.Add("@StartTime", SqlDbType.DateTime).Value = startDate;
commAdvanced.Parameters.Add("@EndTime", SqlDbType.DateTime).Value = endDate;
commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = null;
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = null;
E questa è la query:
SELECT * FROM Order
WHERE CreatedOn > CAST(@StartTime as datetime)
AND CreatedOn < CAST(@EndTime as datetime)
AND Order.OrderStatusID = @OrderStatusID
AND Order.CustomerEmail = @PaymentStatusID
sto ottenendo nessun record quando sto facendo che, qualcuno può please help me che cosa ho bisogno di cambiare.
Soluzione
Secondo la vostra domanda, su 4 parametri uno o tutti i parametri potrebbe essere passato al procedimento. E la query ha tutte le colonne controllati per nella clausola dove. Quindi, se ho capito bene, attualmente, non sarà possibile ottenere tutti i record fino a quando tutti e 4 i parametri sono passati con i dati validi.
Prova questo, sto semplicemente la costruzione di una query e quindi eseguirlo. Posso controllare per ciascuno dei parametri di valori nulli e solo i valori dei parametri che non sono nulli sono inclusi nella clausola dove.
declare @sqlstring varchar(1000)
set @sqlstring = 'SELECT * FROM Order WHERE 1=1 '
if @StartTime <> null OR @StartTime <> ''
BEGIN
set @sqlstring = @sqlstring + 'AND CreatedOn > CAST(@StartTime as datetime) '
END
if @EndTime <> null OR @EndTime <> ''
BEGIN
set @sqlstring = @sqlstring + 'AND CreatedOn < CAST(@EndTime as datetime) '
END
if @OrderStatusID <> null OR @OrderStatusID <> ''
BEGIN
set @sqlstring = @sqlstring + 'AND OrderStatusID = @OrderStatusID '
END
if @CustomerEmail <> null OR @CustomerEmail <> ''
BEGIN
set @sqlstring = @sqlstring + 'AND CustomerEmail > @CustomerEmail '
END
print @sqlstring
Exec(@sqlstring)
Altri suggerimenti
presumere che vi sia un errore di battitura nella query di selezione magari provare
AND Order.CustomerEmail = ISNULL(@CustomerEmail, CustomerEmail)
And OrderStatusID = ISNULL(@OrderStatusID, OrderStatusID)
Inoltre non c'è bisogno di lanciare @StartTime ecc datetime. Sono già di quel tipo, no?
È necessario passare in DBNull.Value
per quelli parametro che si vuole lasciare NULL (non solo il null
NET):
commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = DBNull.Value;
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = DBNull.Value;
Questo dovrebbe fare il trucco.
Inoltre: se si specifica un parametro di tipo varchar
o nvarchar
, mi sento di raccomandare a sempre specificare la sua lunghezza
Credo che questo è giù simpy alla tua richiesta di essere non corretta.
Consente di prendere l'esempio di fornire solo @StartTime. La query sarebbe valutato come:
SELECT * FROM Order
WHERE CreatedOn > CAST(@StartTime as datetime)
AND CreatedOn < null
AND Order.OrderStatusID = null
AND Order.CustomerEmail = null
Supponendo NULL ANSI sono ON, non v'è alcun valore che, se confrontato con i rendimenti nulli un risultato vero, quindi il set di risultati vuoto.
Credo che la risposta di Noel è più vicino - vorrei suggerire:
SELECT * FROM Order
WHERE (@StartTime is null or CreatedOn > @StartTime)
AND (@EndTime is null or CreatedOn < @EndTime)
AND Order.OrderStatusID = isnull(@OrderStatusID, Order.OrderStatusID)
AND Order.CustomerEmail = isnull(@CustomerEmail, Order.CustomerEmail)
marc_s è anche corretto - se si desidera in modo esplicito impostare un valore di parametro @ a SQL null, impostarlo come
commAdvanced.Parameters.Add("@CustomerEmail", SqlDbType.nvarchar).Value = DBNull.Value;
commAdvanced.Parameters.Add("@OrderStatusID", SqlDbType.Int).Value = DBNull.Value;
Tuttavia, perché avete fornito i valori di default di null nel proc memorizzato (tranne @OrderStatusID -? Errore di battitura). , in realtà non hanno bisogno di aggiungere questi parametri al comando a tutti
si ricordi:. La soluzione migliore per la manutenibilità non può essere buono per le prestazioni e la scalabilità (e notare il campo di gioco è cambiato da SQL Server 2008)
Questo è piuttosto un grande tema e vi consiglio di leggere dinamici Condizioni di ricerca in T-SQL di Erland Sommarskog.