Akash Asked: 2014-08-09 06:34:17 +0800 CST2014-08-09 06:34:17 +0800 CST 2014-08-09 06:34:17 +0800 CST 我应该检查存储过程中是否存在临时表? 772 是否有任何边缘情况建议在存储过程开始时显式检查、删除和创建临时表,而不是仅仅创建它们? 同样,是否存在在存储过程结束时显式删除它们比让 SQL Server 清理它们更可取的情况? sql-server sql-server-2012 2 个回答 Voted Best Answer Aaron Bertrand 2014-08-09T09:21:21+08:002014-08-09T09:21:21+08:00 关于检查#tbl 在过程开始时检查表是否存在(如果存在则删除)不会有什么坏处,但这取决于您要如何处理该场景,并且在大多数情况下,它不可能已经存在无论如何(至少如果我们谈论的是与该存储过程中定义的相同的#temp 表)。 您使用以下命令检查表是否存在: IF OBJECT_ID('tempdb..#tablename') IS NOT NULL 您无法检查 tempdb.sys.tables,因为实际名称是,并且由于此潜在问题#tablename__________some hex code,您不应该使用。OBJECT_ID('...') > 0 当然,也有例外。想到的两个: 如果你调用了一切#temp,或者#t,或者#x,那么在调用过程之前,这样的表可能已经从外部范围存在。CREATE TABLE #x您可以提出一个案例,在这种情况下您应该删除它并创建您的新案例,但您也可以提出这是您想知道的错误情况 - 所以失败可能没关系。 您实际上可能想要使用在外部范围中创建的#temp 表,并且仅在尚未在该外部范围中定义时才创建一个。这是可能的,我一直使用这种技术,但通常只在我想从我自己不能轻易操作的系统过程中捕获数据时(例如sp_helptext)。所以我可能会这样做: CREATE TABLE #x([Text] NVARCHAR(MAX)); GO CREATE PROCEDURE dbo.myhelp @p SYSNAME AS INSERT #x EXEC sp_helptext @p; GO EXEC dbo.myhelp N'dbo.myhelp'; -- inception GO SELECT [Text] FROM #x; 即使#x在外部定义,这也有效。这是一个糟糕的例子,因为我宁愿使用sys.sql_modules,但我相信您明白这一点,并且可以设想如何使用自己的程序来做到这一点。 在 DROP TABLE #tbl 上; 我认为您是否应该在程序结束时明确删除#temp 表非常有争议,因此将主要基于意见而关闭;请参阅Paul White的这些优秀博客文章,彻底阅读它们,如果您的所有问题都没有得到回答,请返回并制定一个具体问题: 存储过程中的临时表 临时表缓存解释 user507 2014-08-09T06:54:38+08:002014-08-09T06:54:38+08:00 我认为这取决于您如何使用临时表。如果SELECT INTO正在使用,我会先测试,然后再测试drop。事先测试和丢弃将防止可能出现或可能不会出现的不需要的问题,这对我来说只是很好的代码实践。 如果您CREATE TABLE要先创建临时表,我想我会出于习惯而做同样的事情,并试图保持我如何开发程序的标准。有了这个,您可能只需要在过程结束时使用 drop 语句就可以了,已经看到代码在结束时只使用 drop。 如果您在一个团队中,或者即使只有您自己,请提出一个标准并坚持下去。
关于检查#tbl
在过程开始时检查表是否存在(如果存在则删除)不会有什么坏处,但这取决于您要如何处理该场景,并且在大多数情况下,它不可能已经存在无论如何(至少如果我们谈论的是与该存储过程中定义的相同的#temp 表)。
您使用以下命令检查表是否存在:
您无法检查 tempdb.sys.tables,因为实际名称是,并且由于此潜在问题
#tablename__________some hex code
,您不应该使用。OBJECT_ID('...') > 0
当然,也有例外。想到的两个:
如果你调用了一切
#temp
,或者#t
,或者#x
,那么在调用过程之前,这样的表可能已经从外部范围存在。CREATE TABLE #x
您可以提出一个案例,在这种情况下您应该删除它并创建您的新案例,但您也可以提出这是您想知道的错误情况 - 所以失败可能没关系。您实际上可能想要使用在外部范围中创建的#temp 表,并且仅在尚未在该外部范围中定义时才创建一个。这是可能的,我一直使用这种技术,但通常只在我想从我自己不能轻易操作的系统过程中捕获数据时(例如
sp_helptext
)。所以我可能会这样做:即使
#x
在外部定义,这也有效。这是一个糟糕的例子,因为我宁愿使用sys.sql_modules
,但我相信您明白这一点,并且可以设想如何使用自己的程序来做到这一点。在 DROP TABLE #tbl 上;
我认为您是否应该在程序结束时明确删除#temp 表非常有争议,因此将主要基于意见而关闭;请参阅Paul White的这些优秀博客文章,彻底阅读它们,如果您的所有问题都没有得到回答,请返回并制定一个具体问题:
我认为这取决于您如何使用临时表。如果
SELECT INTO
正在使用,我会先测试,然后再测试drop
。事先测试和丢弃将防止可能出现或可能不会出现的不需要的问题,这对我来说只是很好的代码实践。如果您
CREATE TABLE
要先创建临时表,我想我会出于习惯而做同样的事情,并试图保持我如何开发程序的标准。有了这个,您可能只需要在过程结束时使用 drop 语句就可以了,已经看到代码在结束时只使用 drop。如果您在一个团队中,或者即使只有您自己,请提出一个标准并坚持下去。