【发布时间】:2016-03-29 16:28:06
【问题描述】:
目标:保持一年中每个月学生班级排名的运行表
拥有:我的代码为我提供了列
StudentID; '+@DateTXT+'
DateTXT 是动态变量,返回我运行代码的月份。
需求:我正在尝试使用 MERGE、UPDATE、INSERT 函数来运行一次代码并建立一个表:
| StudentID | Jan |
| 56789 | 2 |
| 12345 | 7 |
然后每个月我都会在永久表中添加一个新的月份列:
EXEC('ALTER TABLE StudentRanking
ADD ' + @DateTXT + ' smallint NOT NULL DEFAULT(999)')
| StudentID | Jan | Feb |
| 56789 | 2 | 999 |
| 12345 | 7 | 999 |
我将再次运行二月份的排名代码并将其保存到一个临时表中,我将使用该表与 StudentRanking 表进行合并、更新和插入:
| StudentID | Feb |
| 56789 | 3 |
(note.. student 12345 doesn't come up)
所以我想最终得到一个运行列表:
EXEC('
MERGE StudentRanking AS TARGET
USING ##TEMPDB2 AS SOURCE ON (TARGET.StudentID = SOURCE.StudentID)
WHEN MATCHED AND TARGET.' + @DateTXT + ' <> SOURCE.' + @DateTXT + '
THEN UPDATE SET TARGET.' + @DateTXT + ' = SOURCE.' + @DateTXT + '
WHEN NOT MATCHED BY TARGET THEN
INSERT (StudentID, ' + @Rank_TXT + ')
VALUES (SOURCE.StudentID, SOURCE.' + @Rank_TXT + ') ')
| StudentID | Jan | Feb |
| 56789 | 2 | 3 |
| 12345 | 7 |null |
问题:一些学生离开学校,从而在接下来的几个月中创建了一个空排名(例如 12345 在 2 月份没有排名),所以当我尝试从临时表中插入结果时,我得到了这个错误:
SQL Server Database Error: Cannot insert the value NULL into column 'Feb', table 'tempdb.dbo.##TEMPDB'; column does not allow nulls. UPDATE fails.
我可以做一个 ISNULL(ranking,0) 但我宁愿有空值而不是 0
【问题讨论】:
-
我注意到您正在使用全局临时表。这些对于并发性来说可能是非常有问题的。您收到该错误的原因是您的列的表定义不允许 NULL。
-
这个解决方案太可怕了。为什么不使用正确规范化的表,其中
StudentID和Month构成您的主键?每个月动态地向表中添加列,然后使用动态 SQL 来更新它是灾难的根源。您愿意采用不同的方法吗? -
始终开放学习不同的方法@GarethD 我确实得到了它的工作,但如果你有更好的解决方案的来源,如果你愿意,请发送。
标签: sql sql-server merge null