我想在运行时动态确定要在存储过程中更新哪一列
我有一张表BshForecast
,其中包含以下属性:
projectId, JobTypeId, Year, JanDone, FebDone, MarDone... (for all months)
我有这个无法正常工作的存储过程
CREATE PROCEDURE [dbo].[SP_Update_Done_Last_Month2]
@Project_ID INT,
@Job_Type_ID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @LAST_MONTH INT
SET @LAST_MONTH = DATEPART(MM,DATEADD(MM, -1, GETDATE()))
UPDATE BshForecast
Set (CASE @LAST_MONTH
WHEN 1 THEN JanDone
WHEN 2 THEN FebDone
WHEN 3 THEN MarDone
WHEN 4 THEN AprDone
WHEN 5 THEN MayDone
WHEN 6 THEN JunDone
WHEN 7 THEN JulDone
WHEN 8 THEN AugDone
WHEN 9 THEN SepDone
WHEN 10 THEN OctDone
WHEN 11 THEN NovDone
WHEN 12 THEN DecDone
END) = 0
WHERE
(ProjectId = @Project_ID)
and (JobTypeId = @Job_Type_ID)
and (Year = DATEPART(YY, DATEADD(MM, -1, GETDATE())))
END
您认为似乎是什么问题?什么是正确的方法呢?
答案 0 :(得分:3)
尝试使用以下内容替换SET
子句:
SET
JanDone = case when @LAST_MONTH = 1 then 0 else JanDone end,
FebDone = case when @LAST_MONTH = 2 then 0 else FebDone end,
MarDone = case when @LAST_MONTH = 3 then 0 else MarDone end,
AprDone = case when @LAST_MONTH = 4 then 0 else AprDone end,
MayDone = case when @LAST_MONTH = 5 then 0 else MayDone end,
JunDone = case when @LAST_MONTH = 6 then 0 else JunDone end,
JulDone = case when @LAST_MONTH = 7 then 0 else JulDone end,
AugDone = case when @LAST_MONTH = 8 then 0 else AugDone end,
SepDone = case when @LAST_MONTH = 9 then 0 else SepDone end,
OctDone = case when @LAST_MONTH = 10 then 0 else OctDone end,
NovDone = case when @LAST_MONTH = 11 then 0 else NovDone end,
DecDone = case when @LAST_MONTH = 12 then 0 else DecDone end
答案 1 :(得分:0)
SQL CASE语句仅对字段值进行操作,而不对表字段名称进行操作。
顺便说一句,如果您可以选择删除JanDone,FebDone等字段并映射到引用表,我强烈建议您更改数据库架构。
答案 2 :(得分:0)
您可以展开当前查询以使其准确无误:
Set JanDone = (CASE WHEN @LAST_MONTH = 1 THEN 0 ELSE JanDone END),
FebDone = (CASE WHEN @LAST_MONTH = 2 THEN 0 ELSE FebDone END),
...
您只需要更新每个字段CASE
。
答案 3 :(得分:0)
您可以使用动态SQL 来实现此目的 - 基本上“动态”构建SQL语句,然后在存储过程中执行它。
这样的事情:
CREATE PROCEDURE [dbo].[proc_Update_Done_Last_Month2]
@Project_ID INT,
@Job_Type_ID INT
AS
BEGIN
SET NOCOUNT ON;
DECLARE @LAST_MONTH INT
SET @LAST_MONTH = DATEPART(MM,DATEADD(MM, -1, GETDATE()))
DECLARE @SqlStmt NVARCHAR(MAX)
SET @SqlStmt = N'UPDATE BshForecast SET ' +
CASE @LAST_MONTH
WHEN 1 THEN N'JanDone'
WHEN 2 THEN N'FebDone'
WHEN 3 THEN N'MarDone'
WHEN 4 THEN N'AprDone'
WHEN 5 THEN N'MayDone'
WHEN 6 THEN N'JunDone'
WHEN 7 THEN N'JulDone'
WHEN 8 THEN N'AugDone'
WHEN 9 THEN N'SepDone'
WHEN 10 THEN N'OctDone'
WHEN 11 THEN N'NovDone'
WHEN 12 THEN N'DecDone'
END + N' = 0 WHERE ProjectId = @Project_ID AND JobTypeId = @Job_Type_ID AND Year = DATEPART(YY, DATEADD(MM, -1, GETDATE()))'
PRINT @SqlStmt
EXEC sp_executesql @SqlStmt
END
动态SQL存在问题和问题 - 在开始在项目中使用动态SQL之前,请务必阅读并理解优秀的文章The curse and blessings of dynamic SQL!