【问题标题】:t-sql stored procedure optional var char parameter not working as expectedt-sql 存储过程可选 var char 参数未按预期工作
【发布时间】:2019-12-08 17:19:03
【问题描述】:

我正在构建一个存储过程,以根据来自另一个数据库的查询返回作业列表。此过滤器具有 1 个将始终传递的必需参数和多个可能不一定传递的可选参数。有 4 个可选参数,其中 3 个按预期工作;添加日期、状态和分配。我的“团队”参数没有按预期工作。现在,当不传递团队参数时,它只返回填充了“团队”字段的所有作业,并忽略任何没有设置团队属性的作业。在这种情况下,我需要它来返回所有工作并且不遗漏任何工作。

为了方便可选参数,我做了以下操作;

    IF(@allocation='')
    SET @allocation = '%'

它在where子句中被称为;

    tbl_PN_jobs.JOB_Name LIKE @allocation

这适用于上述 3 个可选参数,但不适用于“团队”参数。我还尝试根据传递的参数构建一个要在 where 子句中使用的字符串,然后将字符串附加到 where 语句的末尾。

    if @team Is NUll OR @team = ''
    SET @teamWhere = ''
    ELSE if @team Is NOT NUll OR @team <> ''
    SET @teamWhere =  ' AND tbl_Structure_Staff_hierarchy.shy_csc_team = ' 
    + @team


    WHERE
    -- filter
    tbl_PN_staffjobs.stf_cando = 1          AND 
    tbl_PN_staffjobs.stf_empno = @required_empno      AND                                 
    tbl_PN_Jobs.Job_Status = @Jobstatus  AND
    tbl_PN_jobs.JOB_Name LIKE @allocation AND
    CONVERT(date,tbl_PN_Jobs.JOB_Added,103) LIKE @dateAdded 
    + @teamWhere

当没有传递团队参数时,这将按预期返回完整的作业列表,但在传递团队时返回 0 个作业。

当某个“团队”通过时,我希望在某个“团队”下的“工作”数据集,并且在没有“团队”通过时返回整个工作列表。

非常感谢您的帮助。

编辑下面的完整过程

USE [diamond]
GO
/****** Object:  StoredProcedure [dbo].[sp_FilterJobs]    Script Date: 31/07/2019 09:10:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      <NM & OB>
-- Create date: <2019-06-20>
-- Description: <Returns jobs of type that can be processed by agent>
-- =============================================
ALTER PROCEDURE [dbo].[sp_FilterJobs] 
    -- Add the parameters for the stored procedure here

    @required_empno INT,
    @Jobstatus NVarchar(20),
    @team varchar(20),  
    @dateAdded nvarchar(max),  --from
    @allocation NvarChar(max)

AS
BEGIN

IF @Jobstatus =''
SET @Jobstatus = 'Active'

Declare @teamWhere As varchar

if @team Is NUll OR @team = ''
SET @teamWhere = ''
ELSE if @team Is NOT NUll OR @team <> ''
SET @teamWhere =  ' AND tbl_Structure_Staff_hierarchy.shy_csc_team = ' + @team


if  @team = ''
SET @team = '%'

IF(@allocation= '')
SET @allocation = '%'

If @dateAdded = ''
SET @dateAdded = '%'
ELSE
SET @dateAdded = CONVERT(DATE,CAST(@dateAdded AS smalldatetime),103)

SELECT
tbl_structure_staff_hierarchy.shy_csc_team,
tbl_structure_staff_hierarchy.shy_LogonID,
tbl_PN_jobs.*, 
tbl_PN_Job_types.Job_Green, 
tbl_PN_Job_types.Job_Amber, 
tbl_PN_Job_types.Job_Red, 
tbl_PN_staffjobs.stf_cando, 
tbl_PN_staffjobs.stf_empno, 
TBL_PN_MEMBERS.mem_COMPANY, 
TBL_PN_MEMBERS.mem_nfd,

DATEDIFF(minute, Job_added, getDate()) AS [MinutesOnly1],
(IIf(DATEDIFF(minute, Job_added, getdate())>[Job_red],'RED',
IIf(DATEDIFF(minute, Job_added, getdate())>[Job_amber],'Amber',
IIf(DATEDIFF(minute, Job_added, getdate())>[job_green],'Green','Blue'))))  AS Colour,
Round(CAST(DATEDIFF(minute, Job_added, getdate()) AS decimal(18,2))/[job_red],2) AS [%ToRed]

FROM
COMPASS_SERVER.compass.dbo.tbl_Structure_Staff_hierarchy RIGHT JOIN
tbl_PN_jobs LEFT JOIN tbl_PN_Job_types (NOLOCK) ON tbl_PN_jobs.JOB_Name = tbl_PN_Job_types.JOB_type INNER JOIN tbl_PN_staffjobs (NOLOCK) ON tbl_PN_Job_types.JOB_type = tbl_PN_staffjobs.stf_JOB_type
LEFT JOIN TBL_PN_MEMBERS (NOLOCK) ON tbl_PN_jobs.JOB_memberNo = tbl_PN_Members.mem_ID ON tbl_Structure_Staff_hierarchy.shy_LogonID = tbl_PN_jobs.Job_Allocate 

WHERE
-- filter
tbl_PN_staffjobs.stf_cando = 1          AND 
tbl_PN_staffjobs.stf_empno = @required_empno      AND                                 
tbl_PN_Jobs.Job_Status = @Jobstatus  AND
tbl_PN_jobs.JOB_Name LIKE @allocation AND
CONVERT(date,tbl_PN_Jobs.JOB_Added,103) LIKE @dateAdded 
AND tbl_Structure_Staff_hierarchy.shy_csc_team = coalesce(nullif(@team, ''), tbl_Structure_Staff_hierarchy.shy_csc_team) 
--+ @teamWhere

--AND tbl_Structure_Staff_hierarchy.shy_csc_team LIKE @team
ORDER BY DATEDIFF(minute, Job_added, getdate()) DESC

OPTION (RECOMPILE)

--AND tbl_Structure_Staff_hierarchy.shy_csc_team = CASE When @team = Null OR @team = '' Then '' ELSE @team END
END

调用代码; (它实际上是来自访问数据库的直通,但目前只是在 SSMS 上对其进行测试。

USE [diamond]
GO

DECLARE @RC int
DECLARE @required_empno int
DECLARE @Jobstatus nvarchar(20)
DECLARE @team varchar(20)
DECLARE @dateAdded nvarchar(max)
DECLARE @allocation nvarchar(max)

-- TODO: Set parameter values here.

EXECUTE @RC = [dbo].[sp_FilterJobs] 
   @required_empno = 52469
  ,@Jobstatus = 'active'
  ,@team = 'topas'
  ,@dateAdded = ''
  ,@allocation = ''
GO

【问题讨论】:

    标签: tsql stored-procedures parameter-passing


    【解决方案1】:

    似乎您正在尝试构建动态查询。那是行不通的。

    尝试只是添加

    AND tbl_Structure_Staff_hierarchy.shy_csc_team = coalesce(nullif(@team, ''),tbl_Structure_Staff_hierarchy.shy_csc_team) 
    

    仅当@team 不为 null 或为空时,才会按团队过滤。

    【讨论】:

    • 您好,感谢您的帮助,所以我刚刚尝试了这个,它适用于通过团队,但仍然做同样的事情,当没有团队通过时不返回任何工作。
    • 这意味着@team 不是 null 也不是 ''。你能检查一下吗?或者提供完整的查询和过程调用示例。
    • 好的,我将在新评论中添加完整的过程和调用。谢谢
    • 欧文,请显示调用“...当没有团队通过...”您也可以尝试这样的CASE:...AND tbl_Structure_Staff_hierarchy.shy_csc_team = CASE When @team = Null OR @team = '' Then tbl_Structure_Staff_hierarchy.shy_csc_team ELSE @team END
    【解决方案2】:

    漫长的解决方案,但有效;拆分为 2 个查询,如果团队已填充,则使用团队过滤器运行,如果团队为空,则没有团队过滤器。谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多