在ms-sql查询if-else块中选择一个临时表



我有一种情况,需要在特定月份提取额外的项目列表。这是一个简化版本。

我认为这可能是阻塞,所以我添加了BEGIN/END块,我确保在代码的开头和结尾删除临时表。我有点困惑,为什么它似乎试图读取ELSE中不适用的部分的行。

这是整个样本代码

IF OBJECT_ID('tempdb..#TheTempTable') IS NOT NULL DROP TABLE #TheTempTable
IF DATENAME(MONTH, GETDATE()) IN (N'March', N'April')
BEGIN
SELECT PartNumber 
INTO #TheTempTable  -- If I comment this out when May this block works
FROM MainPartsTable
UNION
SELECT '999'
END
ELSE 
BEGIN
SELECT PartNumber 
INTO #TheTempTable --this works for March if this line is commmented out
FROM MainPartsTable
END
SELECT * FROM #TheTempTable
IF OBJECT_ID('tempdb..#TheTempTable') IS NOT NULL DROP TABLE #TheTempTable

按原样运行时,我收到一条错误消息,抱怨第二个块中的INTO#TheTempTable:

There is already an object named '#TheTempTable' in the database.

除非我在第二块中注释掉这一行,否则它不起作用

INTO #TheTempTable --this works for March when this line is commented out

如果我把月份改为五月,只有当我在第一个块中注释掉INTO#TheTempTable时,它才有效

IF DATENAME(MONTH, GETDATE()) IN (N'May', N'April')

谢谢!

这是一个解析器问题。您有两条语句试图在批处理中创建对象#TheTempTable。这两个语句不能同时到达并不重要,解析器不是";那个聪明的";。这可以用这个简单的批次复制:

IF 1 = 1 
SELECT 1 AS I INTO #T
ELSE
SELECT 2 AS I INTO #T;

Msg 2714,级别16,状态1,第4行
数据库中已存在名为"#T"的对象。

相反,在IF语句之外创建表,然后在其中创建INSERT

DROP TABLE IF EXISTS #TheTempTable
SELECT PartNumber
INTO #TheTempTable
FROM MainPartsTable
WHERE 1 = 0; --Never true
IF DATENAME(MONTH, GETDATE()) IN (N'March', N'April')
BEGIN
INSERT INTO #TheTempTable (PartNumber)
SELECT PartNumber 
FROM MainPartsTable
UNION ---ALL?
SELECT '999';
END;
ELSE 
BEGIN
INSERT INTO #TheTempTable (PartNumber)
SELECT PartNumber 
FROM MainPartsTable
END;
SELECT * FROM #TheTempTable;
DROP TABLE IF EXISTS #TheTempTable;

当然,整个事情可以简化为以下内容:

SELECT PartNumber
INTO #TheTempTable
FROM(SELECT PartNumber 
FROM MainPartsTable
UNION ALL
SELECT '999'
WHERE DATEPART(MONTH, GETDATE()) IN (3,4))PN; --Language agnostic

最新更新