ContestoSQL DOVE IN dal param o variabile
Siamo attualmente in fase di ripulire un database SQL e abbiamo incontrato una grande quantità di stored procedure che hanno solo lievi differenze tra di loro. Vogliamo consolidarli in un unico processo per facilitare la manutenzione.
Problema
Qui di seguito sono solo due esempi del tipo di stored procedure che stiamo cercando di unire (fare nota, queste sono le versioni, non i procs effettivi semplificati).
stored procedure - Prenotazioni attuali
ALTER PROCEDURE [dbo].[SelectCurrentBookings]
@client_FK INT, @startDate DATETIME, @endDate DATETIME
AS
BEGIN
SELECT ROW_NUMBER() OVER (ORDER BY [Booking].[bookingDateTime]) [RowNumber],
[Booking].[booking_PK] [Booking ID],
[Booking].[bookingDateTime] [Booking Date],
[Booking].[bookingDuration] [Duration],
[Booking].[client] [Client Name],
CASE WHEN [Booking].[bookingStatusCode_FK] IN (4,8,9,7,16) THEN 1 ELSE 0 END [Unserviced],
FROM [Booking]
WHERE [client_FK] = @client_FK
AND [Booking].[bookingStatusCode_FK] IN (1,2,14,17)
AND [Booking].[bookingDateTime] >= @startDate
AND [Booking].[bookingDateTime] < DATEADD(d,1,@endDate)
AND [Booking].[deleted] = 0
END
stored procedure - Archiviato Prenotazioni
ALTER PROCEDURE [dbo].[SelectArchivedBookings]
@client_FK INT, @startDate DATETIME, @endDate DATETIME
AS
BEGIN
SELECT ROW_NUMBER() OVER (ORDER BY [Booking].[bookingDateTime]) [RowNumber],
[Booking].[booking_PK] [Booking ID],
[Booking].[bookingDateTime] [Booking Date],
[Booking].[bookingDuration] [Duration],
[Booking].[client] [Client Name],
CASE WHEN [Booking].[bookingStatusCode_FK] IN (4,8,9,7,16) THEN 1 ELSE 0 END [Unserviced],
FROM [Booking]
WHERE [client_FK] = @client_FK
AND [Booking].[bookingStatusCode_FK] IN (1,2,14,4,9,7,16,13)
AND [Booking].[bookingDateTime] >= @startDate
AND [Booking].[bookingDateTime] < DATEADD(d,1,@endDate)
AND [Booking].[deleted] = 0
END
Il codice che invoca le stored procedure è in VB.NET
Dim Command As DbCommand = _db.GetStoredProcCommand("SelectCurrentBookings")
_db.AddInParameter(Command, "client_FK", DbType.Int32, ClientID)
_db.AddInParameter(Command, "startDate", DbType.DateTime, StartDate)
_db.AddInParameter(Command, "endDate", DbType.DateTime, EndDate)
Return _db.ExecuteDataSet(Command)
Come si può vedere, l'unica differenza tra i proc memorizzati sopra sono i valori forniti a WHERE IN.
C'è un modo per noi di modificare questo e avere l'elenco dei valori forniti attraverso un parametro o una variabile?
È possibile utilizzare [parametri con valori di tabella] (https://msdn.microsoft.com/en-us/library/bb675163%28v=vs.110%29.aspx). In questo caso, si riempie il valore di tabella in VB per primo (ad es. Con 4 righe 1,2,14,17) e si sostituisce la clausola IN con un join a quel parametro del valore di tabella. Nel mio link ci sono alcuni esempi su come farlo. –
Tenere presente che "SQL Server non conserva statistiche sui parametri con valori di tabella." I piani di query potrebbero diventare pazzi. –
@AlexB. grazie per questo suggerimento, non sono sicuro se sto capendo correttamente, ma non introdurrei alcuni problemi di concorrenza? Anche Michael ha dichiarato che i piani di ricerca potrebbero impazzire con questo, che non è l'ideale neanche per noi. – theoriginalbit