Select @变量不工作

Select @variable not working

我似乎无法全神贯注于我遇到的一点情况。我正在尝试使用 if 条件设置变量;我也尝试过使用 case 语句,但一直收到错误。以下是我正在使用的内容,它也是动态的 SQL ...我要设置的变量是@EBP_Allow ...有人可以对此有所了解吗?

我需要它做什么,例如...

 SELECT 
    @EBP_Allow = IF @Year > 2014 THEN DO a SELECT ELSE DO Something else...

我现在拥有的...

SELECT          
    @OU_Allow = Optional_Unit_Allowed_Flag,
    @BU_Allow = Basic_Unit_Allowed_Flag,
    @EU_Allow = Enterprise_Unit_Allowed_Flag,
    @WU_Allow = Whole_Farm_Unit_Allowed_Flag,
    @EBP_Allow = I NEED TO USE SUB SELECT, IF OR CASE TO SET THIS                              
FROM dbo.@YEAR_Insurance_Offer  
WHERE       
    (dbo.@YEAR_Insurance_Offer.State_Code = @StateCode) AND 
    (dbo.@YEAR_Insurance_Offer.County_Code = @CountyCode) AND 
    (dbo.@YEAR_Insurance_Offer.Crop_Code = ''@CropCode'') AND 
    (dbo.@YEAR_Insurance_Offer.Insurance_Plan_ID = @PlanId) @TypeCondition @PracticeCondition

这是一个更新;好像运行的时候还在跳过我的条件...

                                 CASE 
                                    WHEN @YEAR < 2015
                                        THEN ''N''
                                    WHEN @YEAR > 2014
                                        THEN (
                                                SELECT Enterprise_Unit_By_Practice_Allowed_Flag
                                                FROM dbo.@YEAR_Insurance_Offer  
                                                WHERE       
                                                    (dbo.@YEAR_Insurance_Offer.State_Code = @StateCode) AND 
                                                    (dbo.@YEAR_Insurance_Offer.County_Code = @CountyCode) AND 
                                                    (dbo.@YEAR_Insurance_Offer.Crop_Code = ''@CropCode'') AND 
                                                    (dbo.@YEAR_Insurance_Offer.Insurance_Plan_ID = @PlanId) @TypeCondition @PracticeCondition   
                                             )
                                 END

如果我用这个替换 WHEN @Year > 2014...

WHEN @YEAR > 2014
  THEN ''N''

它工作得很好...出于某种原因或其他原因,当我在其中包含 select 时,它告诉我 Enterprise_Unit_By_Practice_Allowed_Flag 是无效列,但事实并非如此?

dbo.@YEAR_Insurance_Offer.State_Code [数据库所有者].[table].[字段名]

Table name as variable

根据这个 table 名称需要是静态的。

老实说,我从未见过变量 table 的名字。此外,我想不出这样做的充分理由。所以这是逻辑错误还是语法错误?

为了设置 @EPB_Allow 你可以使用一个 CASE 语句,你可以添加多个 WHEN 子句来处理不同的情况:

SELECT          
    @OU_Allow = Optional_Unit_Allowed_Flag,
    @BU_Allow = Basic_Unit_Allowed_Flag,
    @EU_Allow = Enterprise_Unit_Allowed_Flag,
    @WU_Allow = Whole_Farm_Unit_Allowed_Flag,
    @EBP_Allow = CASE 
                     WHEN @Year > 2014 
                         THEN (SELECT column FROM Table where conditions1...) 
                     WHEN @Year > 2013
                         THEN (SELECT column FROM Table where conditions2...)
                     ELSE (SELECT column FROM Table where conditions3...)
                 END                              
FROM dbo.@YEAR_Insurance_Offer  
WHERE       
    (dbo.@YEAR_Insurance_Offer.State_Code = @StateCode) AND 
    (dbo.@YEAR_Insurance_Offer.County_Code = @CountyCode) AND 
    (dbo.@YEAR_Insurance_Offer.Crop_Code = ''@CropCode'') AND 
    (dbo.@YEAR_Insurance_Offer.Insurance_Plan_ID = @PlanId) 
    @TypeCondition @PracticeCondition

此外,请确保如果您已将 @EBP_Allow 定义为 NVARCHAR,那么您必须确保数据类型 return 由选择您想要的值的查询编辑分配变量是相同的数据类型(否则使用 conversion functions)。

并且您必须确保您在 THEN 部分中指定的查询将 return 只有一个结果。

好的,首先,您似乎陷入了每年创建新 table 的可怕做法。这是一个巨大的数据库反模式,如果这是您这样做的第一年,我建议您立即重新设计,因为随着时间的推移,这会变得越来越难处理。

如果你做不到,那么至少从中吸取教训,以后再也不允许任何人设计这样的table。在企业级数据库中,您可以按日期进行分区,在较小的数据库中,您不需要有不同的 tables 只是一个 where 子句来按年份和良好的索引进行过滤。

但您似乎无法使用动态 SQL 来做所有事情(这是一个可怕的设计选择的另一个原因)。所以你不妨学习一下如何正确使用dynamic SQl。

在尝试针对此数据库设计编写代码之前,请先阅读并彻底理解此 link:

http://www.sommarskog.se/dynamic_sql.html

下面是一个示例,说明如何构建和查看为动态 SQl 语句生成的 SQl。这将帮助您在尝试执行之前正确地构建语句。

declare @SQl nvarchar (max), @year nchar (4) = '2014'
set @sql = 'SELECT Enterprise_Unit_By_Practice_Allowed_Flag
    FROM dbo.' +@YEAR+ '_Insurance_Offer  
    WHERE  dbo.'+ @YEAR + '_Insurance_Offer.State_Code = @StateCode'
Print @sql   

由于您是在存储过程中执行此操作,因此所有这些都应该设计有一个调试变量,用于显示任何构建的 SQL。它不需要在生产中的调试模式下 运行 ,但是当你遇到问题时(你不可能预见到每个变量都将成为创建动态 sql 语句的一部分并且几乎 100% 的可能性你会遇到奇怪的错误,你必须在以后进行故障排除。所以你需要在你用动态 SQl 编写的每个过程中内置故障排除能力。

当然要执行你需要学会使用sp_executesql。

但请认真阅读 link,与您的经理和同事分享 link,并思考更好的方法。