我创建了以下存储过程,其中用户传递输入参数以获取数据。输入参数是可选的,即仅传递一个参数应该会产生一些数据。
这是我的代码。
ALTER PROC [dbo].[SPR_ECRM_CASE_INFORMATION]
@ID_APPLICATION_NO NVARCHAR(20),
@TX_ID_NO NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON
IF (@ID_APPLICATION_NO IS NOT NULL ) OR (LEN(@ID_APPLICATION_NO) > 0) AND ((@TX_ID_NO IS NOT NULL) OR (LEN(@TX_ID_NO) > 0))
BEGIN
SELECT DISTINCT
[A].[ID_APPLICATION_NO]
,[A].[TX_APPLICATION_STATUS]
FROM [VW_T_APPLICATION] As [A]
INNER JOIN [CT_L1_APPLICATION_STATUS] [L] ON [L].[TX_L1_APPLICATION_STATUS_CODE] = [A].[TX_APPLICATION_STATUS_CODE]
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [I] WITH(NOLOCK) ON [I].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[II].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [II] WITH(NOLOCK)
WHERE [II].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [II].[CD_APPLICANT_TYPE] = 81
AND [II].[IN_ACTIVE] = 1
ORDER BY
[II].[ID_APPLICATION_APPLICANT] DESC)
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [J] WITH(NOLOCK) ON [J].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[JJ].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [JJ] WITH(NOLOCK)
WHERE [JJ].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [JJ].[CD_APPLICANT_TYPE] = 82
AND [JJ].[IN_ACTIVE] = 1
ORDER BY
[JJ].[ID_APPLICATION_APPLICANT] DESC)
WHERE
[I].[TX_ID_NO] = @TX_ID_NO AND [J].[TX_ID_NO] = @TX_ID_NO
AND
[A].[TX_APPLICANT_ID_NO] = @ID_APPLICATION_NO
AND
[A].[IN_ACTIVE] = 1
END
ELSE IF (@ID_APPLICATION_NO IS NOT NULL) OR (LEN(@ID_APPLICATION_NO) > 0)
BEGIN
SELECT DISTINCT
[A].[ID_APPLICATION_NO]
,[A].[TX_APPLICATION_STATUS]
FROM [VW_T_APPLICATION] As [A]
INNER JOIN [CT_L1_APPLICATION_STATUS] [L] ON [L].[TX_L1_APPLICATION_STATUS_CODE] = [A].[TX_APPLICATION_STATUS_CODE]
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [I] WITH(NOLOCK) ON [I].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[II].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [II] WITH(NOLOCK)
WHERE [II].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [II].[CD_APPLICANT_TYPE] = 81
AND [II].[IN_ACTIVE] = 1
ORDER BY
[II].[ID_APPLICATION_APPLICANT] DESC)
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [J] WITH(NOLOCK) ON [J].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[JJ].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [JJ] WITH(NOLOCK)
WHERE [JJ].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [JJ].[CD_APPLICANT_TYPE] = 82
AND [JJ].[IN_ACTIVE] = 1
ORDER BY
[JJ].[ID_APPLICATION_APPLICANT] DESC)
WHERE
[A].[TX_APPLICANT_ID_NO] = @ID_APPLICATION_NO
AND
[A].[IN_ACTIVE] = 1
END
ELSE IF (@TX_ID_NO IS NOT NULL) OR (LEN(@TX_ID_NO) > 0)
BEGIN
SELECT DISTINCT
[A].[ID_APPLICATION_NO]
,[A].[TX_APPLICATION_STATUS]
FROM [VW_T_APPLICATION] As [A]
INNER JOIN [CT_L1_APPLICATION_STATUS] [L] ON [L].[TX_L1_APPLICATION_STATUS_CODE] = [A].[TX_APPLICATION_STATUS_CODE]
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [I] WITH(NOLOCK) ON [I].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[II].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [II] WITH(NOLOCK)
WHERE [II].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [II].[CD_APPLICANT_TYPE] = 81
AND [II].[IN_ACTIVE] = 1
ORDER BY
[II].[ID_APPLICATION_APPLICANT] DESC)
LEFT JOIN [VW_ST_APPLICATION_APPLICANT] [J] WITH(NOLOCK) ON [J].[ID_APPLICATION_APPLICANT] = (SELECT TOP 1
[JJ].[ID_APPLICATION_APPLICANT]
FROM
[ST_APPLICATION_APPLICANT] [JJ] WITH(NOLOCK)
WHERE [JJ].[ID_APPLICATION_GUID] = [A].[ID_APPLICATION_GUID]
AND [JJ].[CD_APPLICANT_TYPE] = 82
AND [JJ].[IN_ACTIVE] = 1
ORDER BY
[JJ].[ID_APPLICATION_APPLICANT] DESC)
WHERE
[I].[TX_ID_NO] = @TX_ID_NO OR [J].[TX_ID_NO] = @TX_ID_NO
AND
[A].[IN_ACTIVE] = 1
END
ELSE
BEGIN
RETURN NULL
END
END
我已经使用过if if else条件,但是它无法返回数据。
DECLARE @A NVARCHAR(30)
DECLARE @B NVARCHAR(20)
SET @A = 'C192'
SET @B = 'ABC'
EXEC SPR_ECRM_CASE_INFORMATION @A, ''
EXEC SPR_ECRM_CASE_INFORMATION '', @B
EXEC SPR_ECRM_CASE_INFORMATION '', ''
首先,else if条件失败并且我的代码在这里是多余的。有没有更好的方法来优化这一点。感谢您的帮助。
答案 0 :(得分:1)
如果要优化性能,则可以为每个查询创建一个过程。每个人都会得到自己的查询计划。您可以在此过程中分别调用。
查看每个查询,我在ON子句中看到了子查询。我还看到了NOLOCK,我通常认为这是一个不好的信号。另请参见DISTINCT。这些都是可以简化查询的线索。这样,SQL Server将更有可能优化查询。 (您可以通过多种方式要求同一件事。逻辑越复杂,SQL查找最佳计划的可能性就越小。)
如果[VW_T_APPLICATION]中的数据已经不同,则摆脱DISTINCT并使用EXISTS代替LEFT JOINS-一个EXISTS代表81,一个EXISTS代表82。(我假设您不需要这些列)
“ VW”的使用表示视图的使用。该视图可以隐藏很多妨碍简单查询的逻辑。
答案 1 :(得分:0)
这部分(您的第一个IF)在包围式方面是否正确?如果@ID_Application_No不为NULL,它将运行,无论@TX_ID_No是否具有值。
IF (@ID_APPLICATION_NO IS NOT NULL ) OR (LEN(@ID_APPLICATION_NO) > 0) AND ((@TX_ID_NO IS NOT NULL) OR (LEN(@TX_ID_NO) > 0))
我猜你也想要
a)ID_Application_No部分周围的方括号,例如
IF ((@ID_APPLICATION_NO IS NOT NULL ) OR (LEN(@ID_APPLICATION_NO) > 0)) AND ((@TX_ID_NO IS NOT NULL) OR (LEN(@TX_ID_NO) > 0))
或b)希望它为AND(这是我最可能的猜测),例如,
IF (@ID_APPLICATION_NO IS NOT NULL ) AND (LEN(@ID_APPLICATION_NO) > 0) AND ((@TX_ID_NO IS NOT NULL) OR (LEN(@TX_ID_NO) > 0))
请注意,您可以简化一些操作,例如,当您拥有IF (@ID_APPLICATION_NO IS NOT NULL) OR (LEN(@ID_APPLICATION_NO) > 0)
时,如果第二部分为true,则第一部分将始终为true。在这种情况下,您只能使用IF (@ID_APPLICATION_NO IS NOT NULL)
,它将得到相同的结果。