如何通过多个选择查询设置声明的参数

时间:2019-01-09 17:17:38

标签: sql tsql sql-server-2016

我需要设置一个参数,因此执行查询的人只需要在一个地方修改该参数,而不必在多个查询的每个Where子句中对其进行设置。

我不断收到错误消息“必须声明标量变量“ @REGION”,我不知道如何使用已研究的内容解决此问题。此外,我的假设是代码可以进行更优化,但是超出了我的技术能力,也超出了执行此代码能力的人。

USE ADMIN;
DECLARE @REGION NVARCHAR(255)
SET @REGION = 'Region 20 - Midwest';

SELECT [Account Code Description]
    ,[Level 3 Organization Name]
    ,COUNT([Code - Fix Comp]) AS WO_VOL_52
    ,CAST((CAST(SUM([Code - Fix Comp]) AS FLOAT)/CAST(COUNT([Code - Fix Comp]) AS FLOAT))  AS DECIMAL(18,3)) AS OTC_52
    ,CAST((CAST(SUM([Code - Manager Comp]) AS FLOAT)/CAST(COUNT([Code - Manager Comp]) AS FLOAT))  AS DECIMAL(18,3)) AS MR_52
    ,CAST((CAST(SUM([Code - Disagree Comp]) AS FLOAT)/CAST(COUNT([Code - Disagree Comp]) AS FLOAT))  AS DECIMAL(18,3)) AS SAT_52
    ,CAST((CAST(SUM([Code - Recall]) AS FLOAT)/CAST(COUNT([Code - Recall]) AS FLOAT))  AS DECIMAL(18,3)) AS RECALL_52

FROM [dbo].[Manager Review Data]

WHERE [52WK] LIKE 'YES'
    AND [Account Code Description] NOT IN ('Insurance','RECURRING SERVICES')
    AND [Level 3 Organization Name] = @REGION

GROUP BY [Account Code Description],[Level 3 Organization Name]

我希望在设置参数后,使用@Region会在所有使用该变量的查询中调用该参数。

1 个答案:

答案 0 :(得分:0)

通常,我将元数据表用于此类功能。下面的示例代码为您提供了元数据表的原型。用户将执行[utility]。[set__metadata]过程来设置值,然后您将让所有脚本调用内联函数以获取值。或者,您可以“设置”许多元数据值,并且只需在每个脚本的顶部设置一个变量,即可让用户键入要搜索的内容。

如果您有任何疑问,请告诉我。您会发现它是一个非常有用的构造,既可以避免代码中的硬编码常量(需要重新构建/重新部署代码),也可以轻松更改代码中出现的值,并给出简单易用的值。记住那些值的名字。我通常使用“ category.class.type”。您可能应该使用一些标准化的命名约定。我避免使用大写字母,因为可能会出现大小写错误(.NET组件选择性区分大小写)。但是,请使用对您有意义的命名约定。

您可能还决定添加“列表”视图或功能,以便您或其他用户可以轻松查看所有可用的元数据值。

use [test];

go

if schema_id(N'utility') is null
  execute (N'create schema utility');

go

if object_id(N'[utility].[metadata]', N'U') is not null
  drop table [utility].[metadata];

go

create table [utility].[metadata]
  (
     [key]     [nvarchar](256)
     , [value] [nvarchar](256)
  );

go

if object_id(N'[utility].[set__metadata]', N'P') is not null
  drop procedure [utility].[set__metadata];

go

create procedure [utility].[set__metadata] @key     [nvarchar](256)
                                           , @value [nvarchar](256)
as
  begin
      merge into [utility].[metadata] as [target]
      using (values(@key
            , @value)) as [source] ([key], [value])
      on [source].[key] = [target].[key]
      when not matched then
        insert ([key]
                , [value])
        values ([key]
                , [value])
      when matched then
        update set [target].[key] = [source].[key];
  end;

go

if object_id(N'[utility].[get__metadata]', N'FN') is not null
  drop function [utility].[get__metadata];

go

create function [utility].[get__metadata] (@key [nvarchar](450))
returns [nvarchar](256)
as
  begin
      declare @value [nvarchar](max)

      select @value = [value]
      from   [utility].[metadata]
      where  [key] = @key;

      return @value;
  end;

GO

execute [utility].[set__metadata]
  @key = N'region.southwest.texas'
  , @value=N'hot and humid';

go

execute [utility].[set__metadata]
  @key = N'region.pacific_northwest.seattle'
  , @value=N'cold and rainy';

go

select [utility].[get__metadata](N'region.southwest.texas');

go 

select [utility].[get__metadata](N'region.pacific_northwest.seattle');

go