【发布时间】:2022-01-18 18:23:53
【问题描述】:
我不完全理解 Transact-SQL 中的“USE”语句以及它如何影响临时表的范围。我在一个数据库中有一个用户定义的表类型,但在另一个数据库中没有,我发现我需要“使用”该数据库才能定义该类型的表。在查询的前面,我定义了一个临时表。在“USE”语句之后,SSMS 不会将临时表识别为有效的对象名称,但我仍然可以从中查询而不会出错。
我的SQL查询的骨架如下:
USE MYDATABASE1
[……一堆我没写的代码……]
SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE
USE MYDATABASE2
DECLARE @MYTABLE MyUserDefinedTableType -- this table type only exists in MYDATABASE2
INSERT INTO @MYTABLE(Col1, Col2)
SELECT Col1, Col2 FROM (SELECT * FROM MYDATABASE2.dbo.SOME_TABLE_VALUED_FUNCTION(param1, param2)) T
SELECT A.*, B.Col2
FROM #TEMP_TABLE A
CROSS APPLY DATABASE2.dbo.SOME_OTHER_TABLE_VALUED_FUNCTION(@MYTABLE, A.SomeColumn) B
在最后一个 SELECT 语句中,SSMS 在“A.*”和“#TEMP_TABLE”下有红色波浪线,但运行查询没有错误。
所以我的问题是:即使我的查询仍然有效,我是否在做“错误”的事情?假设初始的“USE MYDATABASE1”是必要的,那么在仍然将#TEMP_TABLE 作为有效对象名称的同时切换数据库的正确方法是什么? (请注意,将#TEMP_TABLE 的定义移到“USE MYDATABASE2”之后只会将问题转移到#SOME_EARLIER_TEMP_TABLE。)
【问题讨论】:
-
智能感知并非万无一失。就像拼写检查器会标记正确的单词(直到您将其添加到其字典中)。 SSMS(和 ADS)still 将
GO {n}(其中{n}是一个整数)标记为错误,但应用程序完全可以识别语法,它需要重复该批次n次,例如。如果您正在运行 SQL 并且它没有出错,那么它是有效的。 -
你的代码没问题。 SSMS 刚刚发现没有
#TEMPTABLE定义。从SELECT * INTO #TEMP_TABLE FROM #SOME_EARLIER_TEMP_TABLE推断定义有点超出了它的能力。 -
@Serg 我应该澄清一下,如果 SSMS 在“USE MYDATABASE2”之前,SSMS 可以毫无问题地识别 #TEMP_TABLE,这就是我推断它与更改数据库有关的方式。但感谢您确认这是 SSMS 的问题,而不是我的代码。
-
智能感知可能正在解析文档并使用最近找到的
use作为参考基础。就我个人而言,我发现内置的智能感知非常简单,并且更喜欢 Redgate SQLPrompt 替代方案。临时表的范围也没有问题。 -
说 DECLARE @MYTABLE Mydatabase2.MyUserDefinedTableType 是否有效?这样就不需要第二个 USE 语句了。
标签: sql sql-server