我正在使用以下代码检查临时表是否存在,并在重新创建之前删除该表是否存在。 只要我不更改列,它就可以正常工作。 如果以后再添加一列,则会显示“无效列”错误。 请让我知道我在做什么错。
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
)
select company, stepid, fieldid from #Results
--Works fine to this point
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
NewColumn NVARCHAR(50)
)
select company, stepid, fieldid, NewColumn from #Results
--Does not work
#1楼
这对我有用 : social.msdn.microsoft.com/Forums/en/transactsql/thread/02c6da90-954d-487d-a823-e24b891ec1b0?prof = required
if exists (
select * from tempdb.dbo.sysobjects o
where o.xtype in ('U')
and o.id = object_id(N'tempdb..#tempTable')
)
DROP TABLE #tempTable;
#2楼
由于OBJECT_ID
对我不起作用,所以请在我这边留言。 它总是返回
`#tempTable不存在
..即使确实存在。 我只是发现它以不同的名称存储(后缀_
下划线),如下所示:
#tempTable________
这对我来说很好:
IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#tempTable%') BEGIN
DROP TABLE #tempTable;
END;
#3楼
创建临时表后,通常会遇到此错误; 检查SQL语句是否有错误的代码将看到“旧”临时表,并在以后的语句中返回错误的列数计数,就好像从未删除临时表一样。
在已经创建了具有较少列的版本之后更改了临时表中的列数之后,请删除该表,然后运行查询。
#4楼
无需dropping
并重新创建临时表,您可以truncate
并重新使用它
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
Truncate TABLE #Results
else
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
)
如果使用的是Sql Server 2016
或Azure Sql Database
使用以下语法删除临时表并重新创建它。 更多信息在这里MSDN
句法
DROP TABLE [如果存在] [database_name。 [schema_name]。 | schema_name。 ] table_name [,... n]
查询:
DROP TABLE IF EXISTS tempdb.dbo.#Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
)
#5楼
我的代码使用更改的Source
表和必须与这些更改匹配的Destination
表。
--
-- Sample SQL to update only rows in a "Destination" Table
-- based on only rows that have changed in a "Source" table
--
--
-- Drop and Create a Temp Table to use as the "Source" Table
--
IF OBJECT_ID('tempdb..#tSource') IS NOT NULL drop table #tSource
create table #tSource (Col1 int, Col2 int, Col3 int, Col4 int)
--
-- Insert some values into the source
--
Insert #tSource (Col1, Col2, Col3, Col4) Values(1,1,1,1)
Insert #tSource (Col1, Col2, Col3, Col4) Values(2,1,1,2)
Insert #tSource (Col1, Col2, Col3, Col4) Values(3,1,1,3)
Insert #tSource (Col1, Col2, Col3, Col4) Values(4,1,1,4)
Insert #tSource (Col1, Col2, Col3, Col4) Values(5,1,1,5)
Insert #tSource (Col1, Col2, Col3, Col4) Values(6,1,1,6)
--
-- Drop and Create a Temp Table to use as the "Destination" Table
--
IF OBJECT_ID('tempdb..#tDest') IS NOT NULL drop Table #tDest
create table #tDest (Col1 int, Col2 int, Col3 int, Col4 int)
--
-- Add all Rows from the Source to the Destination
--
Insert #tDest
Select Col1, Col2, Col3, Col4 from #tSource
--
-- Look at both tables to see that they are the same
--
select *
from #tSource
Select *
from #tDest
--
-- Make some changes to the Source
--
update #tSource
Set Col3=19
Where Col1=1
update #tSource
Set Col3=29
Where Col1=2
update #tSource
Set Col2=38
Where Col1=3
update #tSource
Set Col2=48
Where Col1=4
--
-- Look at the Differences
-- Note: Only 4 rows are different. 2 Rows have remained the same.
--
Select Col1, Col2, Col3, Col4
from #tSource
except
Select Col1, Col2, Col3, Col4
from #tDest
--
-- Update only the rows that have changed
-- Note: I am using Col1 like an ID column
--
Update #tDest
Set Col2=S.Col2,
Col3=S.Col3,
Col4=S.Col4
From ( Select Col1, Col2, Col3, Col4
from #tSource
except
Select Col1, Col2, Col3, Col4
from #tDest
) S
Where #tDest.Col1=S.Col1
--
-- Look at the tables again to see that
-- the destination table has changed to match
-- the source table.
select *
from #tSource
Select *
from #tDest
--
-- Clean Up
--
drop table #tSource
drop table #tDest
#6楼
我最近看到DBA做了类似的事情:
begin try
drop table #temp
end try
begin catch
print 'table does not exist'
end catch
create table #temp(a int, b int)
#7楼
我认为问题在于您需要在两者之间添加GO语句以将执行分为几批。 作为第二个删除脚本,即IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
没有删除作为单个批处理的一部分的temp表。 您可以尝试以下脚本吗?
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
)
GO
select company, stepid, fieldid from #Results
IF OBJECT_ID('tempdb..#Results') IS NOT NULL
DROP TABLE #Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
NewColumn NVARCHAR(50)
)
GO
select company, stepid, fieldid, NewColumn from #Results
#8楼
现在,如果您使用的是SQL Server(2016+)的新版本之一,则可以使用以下语法。
DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...)
#9楼
是的,“列无效”,此错误是从“从#Results选择公司,stepid,fieldid,NewColumn”行引发的。
运行t-sql分为两个阶段,
首先,进行解析,在此阶段中,SQL Server将检查您提交的sql字符串(包括表的列)的更正,并优化查询以实现最快的恢复。
第二,运行,检索数据。
如果表#Results存在,则解析过程将检查您指定的列是否有效,否则(表不存在)解析将通过您指定的检查列。
#10楼
只需一行代码即可完成:
IF OBJECT_ID('tempdb..#tempTableName') IS NOT NULL DROP TABLE #tempTableName;
#11楼
更改临时表中的列时,必须先删除表,然后再次运行查询。 (是的,这很烦人。这就是您要做的。)
我一直认为这是因为“无效列”检查是在运行查询之前由解析器完成的,因此它是基于表中被删除之前的列的.....这就是pnbs所说的。
#12楼
我无法重现该错误。
也许我不了解这个问题。
在SQL Server 2005中,以下内容对我来说很好用,第二个选择结果中显示了额外的“ foo”列:
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT )
GO
select company, stepid, fieldid from #Results
GO
ALTER TABLE #Results ADD foo VARCHAR(50) NULL
GO
select company, stepid, fieldid, foo from #Results
GO
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
#13楼
pmac72正在使用GO将查询分解为多个批次,并使用ALTER。
您似乎正在运行同一批,但在更改后又运行了两次:DROP ... CREATE ...编辑... DROP ... CREATE ..
也许发布您的确切代码,以便我们可以看到发生了什么。
#14楼
该声明应具有顺序
- 更改表的语句
- 走
- 选择语句。
在两者之间没有'GO'的情况下,整个过程将被视为一个脚本,并且当select语句查找该列时,将不会找到它。
使用'GO',它将把直到'GO'的脚本部分视为一个批处理,并在'GO'之后进入查询之前执行。