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.

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top