我正在尝试以下查询
if exists (select 1 from emp where eid = 6)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))
end
else
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (newcolumns varchar(100))
end
但我收到了错误
Msg 2714, Level 16, State 1, Line 8
There is already an object named '#columntable' in the database.
有人能说明为什么吗?如果我不写其他部分,同样的查询工作正常。
答案 0 :(得分:7)
遗憾的是,这是一个SQL Server解析器错误(confirmed by Microsoft)。
@DizGrizz也是正确的 - SELECT .. INTO #SomeTable
如果在IF .. ELSE
语句中重复,则无效。
在回答实际问题时,创建然后改变表格(你也只需要检查和删除一次)......
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL
BEGIN
DROP TABLE #MyTempTable
END
CREATE TABLE #MyTempTable (DummyColumn BIT)
IF EXISTS (SELECT 1 FROM EMP WHERE EID = 6)
BEGIN
ALTER TABLE #MyTempTable
ADD MyColumnType1 VARCHAR(100)
ALTER TABLE #MyTempTable
DROP COLUMN DummyColumn
END
ELSE
BEGIN
ALTER TABLE #MyTempTable
ADD MyColumnType2 VARCHAR(100)
ALTER TABLE #MyTempTable
DROP COLUMN DummyColumn
END
然而,我遇到的问题与@DizGrizz相同:IF .. ELSE
与SELECT .. INTO #SomeTable
相结合失败。作为一种解决方法,可以选择前0行(即无)来创建具有正确列类型的表。 (这会使脚本与列类型更改隔离,并且还可以避免声明每种类型的痛苦。)然后可以使用INSERT INTO
,前提是IDENTITY_INSERT
设置为ON
以防止错误:
IF OBJECT_ID('tempdb..#MyTempTable') IS NOT NULL
DROP TABLE #MyTempTable
-- This creates the table, but avoids having to declare any column types or sizes
SELECT TOP 0 KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
-- Required to prevent IDENTITY_INSERT error
SET IDENTITY_INSERT #MyTempTable ON
IF @something = 1
BEGIN
-- Insert the actual rows required into the (currently empty) temp table
INSERT INTO #MyTempTable (KeyNm)
SELECT KeyNm
FROM dbo.MyDataTable2
WHERE CatNum = 2
END
ELSE
BEGIN
-- Insert the actual rows required into the temp table
INSERT INTO #MyTempTable (KeyNm)
SELECT KeyNm
FROM dbo.MyDataTable2
WHERE CatNum = 8
END
SET IDENTITY_INSERT #MyTempTable OFF
答案 1 :(得分:6)
在查询结束时不会自动删除临时表,只有在删除当前与数据库的连接或使用DROP TABLE #columntable
明确删除它们时才会删除它们
要么在查询开始时测试表的存在,要么在结束时删除它(最好是两者)
编辑:正如Matrin在评论中所说,这实际上是一个解析错误。如果只在执行时解析SQL,则会得到相同的错误。为了测试这一点,我将您的查询拆分并尝试:
if exists (select 1 from emp where id = 6)
create table #columntable (newcolumns varchar(100))
GO
if not exists (select 1 from emp where id = 6)
create table #columntable (oldcolumns varchar(100))
GO
解析器很满意。有趣的是,如果您更改为使用非临时表,原始查询会解析(我意识到会产生的问题,我只是想知道查询无法解析的原因)。
答案 2 :(得分:2)
如果使用SELECT INTO创建表格,也会出现这种情况......如
IF OBJECT_ID('tempdb..#MyTempTable', 'U') IS NOT NULL
DROP TABLE #MyTempTable
SELECT TOP 1 @MyVariable = ScaleValue
FROM MyDataTable1
WHERE ProductWeight > 1000
IF @MyVariable = 1
BEGIN
SELECT KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
WHERE CatNum = 2
END
ELSE
BEGIN
SELECT KeyNm
INTO #MyTempTable
FROM dbo.MyDataTable2
WHERE CatNum = 8
END
解析器甚至不应该尝试检测到这一点,因为在许多情况下,解析器无法确定表是否已经存在。上面的代码是一个完美的例子......解析器无法确定@MyVariable的值。 我希望有人告诉MS这个错误(我没有他们的耳朵)。
答案 3 :(得分:1)
您可以通过执行以下操作来检查它是否存在:
IF OBJECT_ID('tempdb..#columntable') IS NOT NULL
BEGIN
DROP TABLE #columntable
PRINT 'Dropped table...'
END
答案 4 :(得分:1)
使用全局临时表并将select包装在exec中。
示例:
故障
declare @a int = 1
if object_id('tempdb..##temp') is not null drop table ##temp
if(@a = 1) select * into ##temp from table_1
else if(@a = 2) select * into ##temp from table_2
运
declare @a int = 1
if object_id('tempdb..##temp') is not null drop table ##temp
if(@a = 1) exec('select * into ##temp from table_1')
else if(@a = 2) exec('select * into ##temp from table_2')
这会欺骗那些试图比它更聪明的错误解析器。 和微软 - 请解决这个问题。
答案 5 :(得分:0)
错误是错误的,删除if子句并且运行正常。因此问题在于存在:
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))
答案 6 :(得分:0)
嗯,我得到了答案...... 正如马丁所说,这是一个解析/编译问题。所以我试着改变我的脚本如下
if exists (select 1 from emp where eid = 6)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (oldcolumns varchar(100))
end
go
if exists (select 1 from emp where eid = 1)
begin
if object_id('tempdb..#columntable') is not null
begin
drop table #columntable
end
create table #columntable (newcolumns varchar(100))
end
这对我有用。
答案 7 :(得分:0)
我一直遇到这个问题。我的查询由以下形式的几个连接的 SELECT
语句组成:
DROP TABLE IF EXISTS ##TempTableName
SELECT statement ...
因此,每次我尝试更改 SQL 代码时,都会出现上述错误。我已将所有临时表从 ##global 更改为 #local,现在我可以根据需要多次更改 SQL。所以上面的例子会变成:
DROP TABLE IF EXISTS #TempTableName
SELECT statement ...