2017-06-14 22 views
1

下面的SQL脚本生成的SQL Server配置文件的Invalid object name '#temp'例外,但也SQL Server Management Studio中也不SQLCMD引发异常:寂静异常

create table #temp (id int) 
insert into #temp (id) values (1) 

我只抓住了它通过运行SQL Server Profiler并打开事件“Exception”,可以在配置跟踪属性时在“Events Selection”选项卡上设置该事件。

由于异常往往服务器慢下来,我用一个表变量尝试过类似代码:

declare @temp table (id int) 
insert into @temp (id) values (1) 

上面不仅避免了异常的代码,但也快一边喊它的时候,它comproves通过使用临时表的性能损失:

if (db_id('performance_test') is null) 
    create database performance_test 

go 

use performance_test 

go 

/* --------------------------- */ 
/* stress test with temp table */ 
/* --------------------------- */ 

declare 
    @i int, 
    @sql varchar(max), 
    @start_time datetime, 
    @end_time datetime 

set @i = 0 

set @sql = 'create table #temp (id int)' + Char(13) + Char(10) + 'insert into #temp (id) values (1)' 

set @start_time = getdate() 

while (@i < 10000) 
begin 
    exec (@sql) 
    set @i = @i + 1 
end 

set @end_time = getdate() 

select [Elapsed milliseconds] = datediff(millisecond, @start_time, @end_time) -- outputs 17090 milliseconds 

go 

/* ------------------------------- */ 
/* stress test with table variable */ 
/* ------------------------------- */ 

declare 
    @i int, 
    @sql varchar(max), 
    @start_time datetime, 
    @end_time datetime 

set @i = 0 

set @sql = 'declare @temp table (id int)' + char(13) + char(10) + 'insert into @temp (id) values (1)' 

set @start_time = getdate() 

while (@i < 10000) 
begin 
    exec (@sql) 
    set @i = @i + 1 
end 

set @end_time = getdate() 

select [Elapsed milliseconds] = datediff(millisecond, @start_time, @end_time) -- outputs 10010 milliseconds 

我经常读到一个局部临时表表变量可可交换使用(当然,如果使用单批次的话),但是我认为上述证明的行为可以证明不然。

虽然它有点明显,但值得注意的是,除了不提高,如果我们从insert into在不同批次分开create table

create table #temp (id int) 
go 
insert into #temp (id) values (1) 

这是沉默异常一个SQL Server的错误或者是它的东西这可以称为“按设计特征”?考虑到上面的无声例外,也许总是使用表变量而不是临时表更好。

P.S .:我在SQL Server 2014和SQL Server 2016 Developer版本上都进行过测试,得到的结果相同。

+0

这里的实际问题是什么? –

+0

很确定这个(非)问题的答案可以在这里找到:https://blogs.msdn.microsoft。com/turgays/2013/09/17/exec-vs-sp_executesql/ –

+0

我指的是由'create table'引起的异常,后面跟着'insert into',这是使用SQL Server Profiler捕获的。我在质疑“异常”是否是一个错误,或者它是否被设计成这样。也许创建一个表并在其中插入值是一种错误的编码习惯,这会在SQL Server中引发(无声)异常。 –

回答

0

正如@JeroenMostert指出的那样,异常"Invalid object name"可能在批量重新编译中解决(我不知道)。考虑到“延迟名称解析”过程是一个非常有意义的过程,它是SQL Server社区中的一个已知主题。

下面的第一个链接是我在MSDN上发布的一个问题,由Mohsin_A_Khan在SQL Server中讨论“延迟名称解析”过程回答。其他两个环节有助于理解它是如何工作:

Getting "Invalid object name" by creating a temp table and inserting rows right away

How to find what caused errors reported in a SQL Server profiler trace?

Deferred Name Resolution and Compilation

由于“无效的对象名称”有望因重新编译过程中,不应该通过简单地用一个表变量替换临时表来避免(再次,正如@JeroenMostert指出的那样),我认为这个问题得到了回答。