如何将内部连接的存储过程代码改进为可能的空 tvp
How to improve the code of stored procedure with inner join to possible empty tvp
我想改进以下存储过程的代码。我想将它加入单个 select 语句。你能设计出更好的方法吗?
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
我认为将 2 个选择合并为一个不会改进您的代码。为了进行比较,这里是一个如何做到这一点的例子。我们有 1 个查询,但它更复杂并且可读性较差。
下面的查询是基于您的第二个查询。我通过向 WHERE 语句添加附加条件来修改它。如果 @finDocIdForFilter
为空或 @finDocIdForFilter
包含匹配行,则满足此额外条件。
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)
)
我有一个想法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)
)
我想这可能对你有用。
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 )
)
);
我想改进以下存储过程的代码。我想将它加入单个 select 语句。你能设计出更好的方法吗?
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
我认为将 2 个选择合并为一个不会改进您的代码。为了进行比较,这里是一个如何做到这一点的例子。我们有 1 个查询,但它更复杂并且可读性较差。
下面的查询是基于您的第二个查询。我通过向 WHERE 语句添加附加条件来修改它。如果 @finDocIdForFilter
为空或 @finDocIdForFilter
包含匹配行,则满足此额外条件。
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)
)
我有一个想法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)
)
我想这可能对你有用。
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 )
)
);