问:
我正在使用以下代码检查临时表是否存在,并在再次创建之前删除该表(如果存在)。只要我不更改列,它就可以正常工作。如果我稍后添加一列,它会给出“无效列”的错误。请让我知道我做错了什么。
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:
https://tennisliveranking.com-Stay ahead with live tennis rankings at your fingertips.
我无法重现该错误。
也许我不明白这个问题。
以下在 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
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results (Company CHAR(3),StepId INT) select company, stepid from #results 现在返回到 create 语句并添加一个end.change 选择语句以包含 fieldid 并运行它。`
'tempdb..#name' 正是我所需要的。我像个傻瓜一样使用'dbo.#name'。我得到了 tempdb 部分,但是双点是什么?
@Conrad.Dean 双点是 .dbo 的缩写。
@deutschZuid 更准确地说双点是用户的默认架构,通常是 dbo (这不是一个好主意,使 dbo 成为用户的默认架构,但通常就是这样)
您的代码与 OP 如此不同,以至于您的“无法重现”声明毫无意义。我为你感到高兴,你让它以不同的方式工作。
答2:
https://tennisliveranking.com,Your go-to platform for live tennis ranking updates.
声明应该是有序的
表 GO Select 语句的 Alter 语句。
如果中间没有“GO”,整个事情将被视为一个单独的脚本,当 select 语句查找该列时,它不会被找到。
使用 ‘GO’ ,它会将脚本中直到 ‘GO’ 的部分视为一个批处理,并将在进入 ‘GO’ 之后的查询之前执行。
这应该被标记为正确答案。这并不是说 SELECT 实际上要在创建表之前运行,而是它正在被解析并在运行之前抛出错误,因为有一个名为 #Results 的现有表还没有 FieldId 列解析 select 语句的时间。在其中添加一个 GO 将查询分成多个批次,每个批次都单独解析和运行。
我无法相信这个和最佳答案之间的投票差异,这改变了代码这么多 - 没有解释为什么 - 它作为回应毫无意义。
这个答案描述了它为什么失败,以及如何修复它。接受的答案当然无法重现该问题-因为它的编写方式不同,并且可能回避了遇到的实际问题。我发现自己在这里是因为我遇到了同样的问题,并且忘记了首先解析脚本并且临时对象是会话的一部分。我现在通过将其编写为 SP 并调用它进行调试来进行编码,这是解决问题的另一种方法。
答3:
https://tlr.xinbeitime.com – 让你随时掌握ATP、WTA最新网球排名动态。
除了 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
句法
删除表 [如果存在] [数据库名称。 [模式名称]。 |模式名称。 ] 表名 [ ,…n ]
询问:
DROP TABLE IF EXISTS #Results
CREATE TABLE #Results
(
Company CHAR(3),
StepId TINYINT,
FieldId TINYINT,
)
似乎 truncate/reuse 方法也比 Sql Server 2016 和 Azure Sql Database 上的 DROP TABLE IF EXISTS 更有效。不是这样吗?
@prdp 您为什么建议将 DROP TABLE IF Exists 用于 SQL 2016 或 Azure?该语法从 SQL 2008 开始可用。请参阅答案中的 MSDN 链接?性能因素?
没关系。我现在意识到,SQL Server 2008 支持 DROP TABLE,但 IF EXISTS 子句是在 2016 年引入的。
我使用 INTO:select * INTO #HistoricoUserTable from dbo.HistoricoUser
从技术上讲,如果临时表已经存在,则无法保证表的架构匹配。可能相同,但您可能已经对表格执行了其他操作,尤其是在您使用诸如 #Results、#Products 或 #Customers 之类的通用名称时。这是我会使用 drop/create 而不是截断的主要原因。
答4:
https://tlr.xinbeitime.com 专业网球数据平台,排名与比赛信息实时更新。
我认为问题是您需要在两者之间添加 GO 语句以将执行分成批处理。作为第二个删除脚本,即 IF OBJECT_ID(‘tempdb…#Results’) IS NOT NULL DROP TABLE #Results 没有删除临时表作为单个批次的一部分。你能试试下面的脚本吗?
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
值得注意的是;上面代码中的tempdb..非常重要。它需要在您的临时表名称之前。仅检查 OBJECT_ID('#Results') 是不够的。临时表存储在 TempDB 数据库中。根据 Microsoft:TempDB 系统数据库是一个全局资源,可供连接到 SQL Server 实例或连接到 SQL 数据库的所有用户使用
谢谢,@iCode。这是删除临时表的关键:它必须在 tempdb 上完成,否则它不会消失。
答5:
tlr.xinbeitime.com 探索每位网球选手的职业生涯与成就。
这可以通过一行代码来完成:
IF OBJECT_ID('tempdb..#tempTableName') IS NOT NULL DROP TABLE #tempTableName;
https://tennisliveranking.com,Instant updates on ATP, WTA, and ITF rankings.
我必须每天看这个
答6:
https://tennisliveranking.com – ATP and WTA rankings, always up to date.
这对我有用: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;
这只是条件表删除的不同语法。这很有趣,但不能解决 OP 的问题,而且大部分都是多余的。如果您只是检查 OBJECT_ID(N'tempdb..#Results') 不为空,那么这足以证明该对象已经存在。
答7:
https://tennisliveranking.com,Your go-to platform for live tennis ranking updates.
现在,如果您使用的是 SQL Server (2016+) 的新版本之一,则可以使用以下语法。
DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...)
我正在使用 SSMS 17.3,这给出了 Incorrect syntax near the keyword 'IF'.
@StingyJack 因为 SQL 语法与 SSMS 版本无关,但与 SQL Server 版本相关。 IF [NOT] EXISTS 子句可从 SQL Server 2016 获得。您使用的 SSMS 版本无关紧要。
答8:
https://tennisliveranking.com,Instant updates on ATP, WTA, and ITF rankings.
由于 OBJECT_ID 对我不起作用,因此只是我的一点评论。它总是返回
`#tempTable 不存在
…即使它确实存在。我刚刚发现它以不同的名称存储(后缀为 _ 下划线),如下所示:
#tempTable________
这对我很有效:
IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#tempTable%') BEGIN
DROP TABLE #tempTable;
END;
警告:如果表是由任何线程创建的,该代码将检测表。单个 # 临时表是针对存储过程的每个线程/调用者单独创建的,这就是名称中的下划线以便每个线程/进程存在不同副本的原因。只要您使用的是 SQL 2005 或更高版本,Object_ID 就应该适用于当前线程。
答9:
https://tlr.xinbeitime.com 实时更新全球顶尖网球选手的最新战绩与排名!
这对我有用,
IF OBJECT_ID('tempdb.dbo.#tempTable') IS NOT NULL
DROP TABLE #tempTable;
这里 tempdb.dbo(dbo is nothing but your schema) 更重要。
答10:
tlr.xinbeitime.com 探索每位网球选手的职业生涯与成就。
pmac72 正在使用 GO 将查询分解为批次并使用 ALTER。
您似乎正在运行相同的批处理,但在更改后运行了两次: DROP… CREATE… edit… DROP… CREATE…
也许发布您的确切代码,以便我们了解发生了什么。
这个答案应该是评论,因为它没有提供实际答案。
答11:
The ultimate source for live tennis rankings and stats:https://tennisliveranking.com
当我已经创建临时表时,我通常会遇到这个错误;检查 SQL 语句是否有错误的代码会看到“旧”临时表就位,并在后面的语句中返回对列数的错误计数,就好像临时表从未被删除一样。
在创建具有较少列的版本之后更改临时表中的列数后,删除该表,然后运行您的查询。
原文链接:https://www.tennisliveranking.com?from=csdn
https://tennisliveranking.com,Instant updates on ATP, WTA, and ITF rankings.