sql-server - salida - stored procedure sql server ejemplos
Cómo mejorar el código de procedimiento almacenado con unión interna a posible tvp vacío (3)
Quiero mejorar el código del siguiente procedimiento almacenado. Quiero unirme a una sola declaración de selección. ¿Puedes proponer una mejor manera?
CREATE PROCEDURE [dbo].[pr_FinDocument_Filter]
@finDocIdForFilter [dbo].[GuidList] READONLY,
@filteredSid nvarchar(64),
@filteringOffsetInDay int
AS
BEGIN
IF (@filteredSid is null or @filteringOffsetInDay is null)
BEGIN
RAISERROR(N''arguments must have a value'', 15, 1);
END
IF EXISTS (SELECT 1 FROM @finDocIdForFilter)
BEGIN
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
INNER JOIN @finDocIdForFilter AS fin_doc_for_filter
ON fin_doc_extra.docId = fin_doc_for_filter.Id
AND fin_doc_extra.sid = @filteredSid
WHERE
DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
END
ELSE
BEGIN
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE
fin_doc_extra.sid = @filteredSid
AND DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
END
END
Creo que esto podría funcionar para ti.
SELECT fin_doc_extra.docID
FROM [CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105),
CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND fin_doc_extra.sid = @filteredSid
AND ( ( fin_doc_extra.docId IN ( SELECT fin_doc_for_filter.Id
FROM @finDocIdForFilter ) )
OR ( NOT EXISTS ( SELECT 1
FROM @finDocIdForFilter )
)
);
Creo que fusionar 2 selecciones en una no necesariamente mejorará tu código. A modo de comparación, aquí hay un ejemplo de cómo puedes hacer eso. Tenemos 1 consulta, pero es más compleja y puede percibirse como menos legible.
La siguiente consulta se basa en su segunda consulta. Lo modifiqué agregando una condición adicional a la declaración WHERE. Esta condición adicional se cumplirá si @finDocIdForFilter
está vacío o si @finDocIdForFilter
contiene filas coincidentes.
SELECT fin_doc_extra.docId
FROM
[CpsOther].[dbo].[FinDocumentExtra] AS fin_doc_extra
WHERE
fin_doc_extra.sid = @filteredSid AND
DATEDIFF(DAY, CONVERT(DATE, fin_doc_extra.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND
(
NOT EXISTS(SELECT 1 FROM @finDocIdForFilter)
OR
EXISTS(
SELECT 1
FROM @finDocIdForFilter AS fin_doc_for_filter
ON fin_doc_extra.docId = fin_doc_for_filter.Ida.AssetCode)
)
Tengo una idea sobre left outer join
SELECT TABLEA.Id
FROM
TABLEA
left join TVP
on TVP.Id = TABLEA.Id
WHERE
TABLEA.sid = @filteredSid
AND DATEDIFF(DAY, CONVERT(DATE, TABLEA.value, 105), CONVERT(DATE, GETDATE(), 126)) = @filteringOffsetInDay
AND
(
TVP.Id is not null
OR
NOT EXISTS (SELECT 1 FROM TVP)
)