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,并思考更好的方法。
我似乎无法全神贯注于我遇到的一点情况。我正在尝试使用 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,并思考更好的方法。