Cog*_*ave 44 sql t-sql sql-server sql-server-2012
我编写了一个存储过程来将数据从一个数据库导入和转换到另一个数据库 每次导入都会获取一个公司ID,并导入与该公司相关的所有数据.
为了帮助转换步骤,我使用临时表.作为脚本审查的一部分,我被告知使用表变量而不是临时表.评论者声称,如果我们同时运行两个不同的导入,临时表将被共享并破坏导入.
问题:
EXEC创建一个新范围吗?这是一个人为的脚本示例.
CREATE PROC [dbo].[ImportCompany]
(
@CompanyId AS INTEGER
)
AS
EXEC [dbo].[ImportAddress] @CompanyId = @CompanyId
--Import other data
CREATE PROC [dbo].[ImportAddress]
(
@CompanyId AS INTEGER
)
AS
CREATE TABLE #Companies (OldAddress NVARCHAR(128), NewAddress NVARCHAR(128))
INSERT INTO #Companies(OldAddress, NewAddress)
SELECT
Address as OldAddress,
'Transformed ' + Address as NewAddress
FROM
[OldDb].[dbo].[Addresses]
WHERE
CompanyId = @CompanyId
--Do stuff with the transformed data
DROP TABLE #Companies
EXEC [dbo].[ImportCompany] @CompanyId = 12345
Run Code Online (Sandbox Code Playgroud)
Dam*_*ver 55
来自CREATE TABLE:
本地临时表仅在当前会话中可见
(更重要的是):
如果在可由多个用户同时执行的存储过程或应用程序中创建本地临时表,则数据库引擎必须能够区分由不同用户创建的表[原文如此 - 几乎可以肯定这应该说会话不是用户].数据库引擎通过在每个本地临时表名称内部附加数字后缀来完成此操作.
这恰恰反驳了谁说他们将被分享的观点.
此外,DROP TABLE您无需在程序结束时(再次从同一链接):
存储过程完成时,将自动删除在存储过程中创建的本地临时表
Dar*_*ren 34
## 用于全局临时表 - 将可用于不同的导入.
# 用于本地临时表,仅在当前/内部范围内可用.
我只是花了几个小时努力找出为什么触发器中使用的临时表表现得很奇怪。然后我意识到临时表与用于插入触发触发器的数据的存储过程中的临时表具有相同的名称。我现在意识到这对我来说应该是显而易见的,但这是一个典型的案例,在试图找出为什么某些事情没有意义时忽略了最明显的原因。
因此,重要的是要记住,当一个存储过程调用另一个存储过程或触发触发器时,临时表名称在这些过程中必须是唯一的,以防止出现不需要的副作用。
此外 - 即使在内部存储过程中执行以下代码时,它也不会按预期运行。由于外部存储过程似乎锁定了临时表名称。
IF OBJECT_ID('tempdb..#TempTable') IS NOT NULL
DROP TABLE #TempTable
Run Code Online (Sandbox Code Playgroud)