选择@variable无效

时间:2015-01-23 14:35:21

标签: sql sql-server dynamic

我似乎无法将我的想法包围在我所拥有的一点情况中。我试图使用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''

它工作得很好......出于某种原因,当我在那里选择它时,它告诉我Enterprise_Unit_By_Practice_Allowed_Flag是一个无效的列,但它不是?

3 个答案:

答案 0 :(得分:3)

要设置@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,则必须确保查询返回的数据类型选择要为变量赋值的值是相同的数据类型(否则使用conversion functions)。

您必须确保在THEN部分中指定的查询只返回一个结果。

答案 1 :(得分:1)

好的,首先看来你已经陷入了每年创造新桌子的可怕做法。这是一个巨大的数据库反模式,如果这是你做到这一年的第一年,我建议立即重新设计,因为随着你增加更多年,这变得越来越难以处理。

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

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

在尝试针对此数据库设计编写代码之前,请先阅读并仔细理解此链接:

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   

由于您在Stored procs中执行此操作,因此所有这些都应该设计有一个调试变量,用于显示任何构建的SQL。它不需要在生产中以调试模式运行,但是当你遇到问题时(并且你不可能预见到每个变量都将成为创建动态sql语句的一部分并且接近于你有可能会遇到以后需要排除故障的错误概率。所以你需要在使用动态SQl编写的每个进程中建立故障排除能力。

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

但是真的阅读了这个链接,与你的经理和同事分享链接,并考虑更好的方法来做到这一点。

答案 2 :(得分:-1)

DBO。@ YEAR_Insurance_Offer.State_Code [databaseowner] [表] [字段名]

Table name as variable

根据此表,名称必须是静态的。

老实说,我从未见过变量表名。此外,我想不出有这么好的理由。那么这是逻辑错误还是语法错误?