Pet*_*ier 8 sql-server ddl tempdb temporary-tables
将一个 quickie proc 放在一起以帮助调试,我遇到了一个似乎是编译器错误的地方。
create proc spFoo
@param bit
as
begin
if @param = 0
begin
select *
into #bar
from [master].dbo.spt_values
-- where number between ...
end
else
begin
select top 10 *
into #bar
from [master].dbo.spt_values
order by newid();
end;
end;
Run Code Online (Sandbox Code Playgroud)
尝试上述返回以下错误
消息 2714,级别 16,状态 1,过程 spFoo,第 19 行
数据库中已经有一个名为“#bar”的对象。
在人类可读的意义上,proc 似乎很好:select into由于它们被包裹在if-else块中,因此只会执行一个语句。不过很好,SQL Server 无法确认这些语句在逻辑上是否相互排斥。也许更令人困惑的是,当将drop table #foo放在 if-else 块中时错误仍然存在(假设它会告诉编译器取消分配对象名称),如下所示。
create proc spFoo
@param bit
as
begin
select top 1 *
into #bar
from [master].dbo.spt_values
if @param = 0
begin
drop table #bar;
select *
into #bar
from [master].dbo.spt_values
-- where number between ...
end
else
begin
drop table #bar;
select top 10 *
into #bar
from [master].dbo.spt_values
order by newid();
end;
end;
Run Code Online (Sandbox Code Playgroud)
proc本身很好。我吸收了它并编写了create table #foo( ... )andinsert #foo ( ... )语句,我一直试图跳过select * into 语法。在这一点上,我只是想理解为什么编译器会用懒人语法来抨击我。我唯一能想到的是 DDL 命令保留了对象名称IN TEMPDB。
为什么是粗体字?
create proc spIck
as
begin
create table #ack ( col1 int );
drop table #ack;
create table #ack ( colA char( 1 ) );
drop table #ack;
end;
Run Code Online (Sandbox Code Playgroud)
这失败了,错误代码与上面相同。但是以下...
create proc spIck
as
begin
create table ack ( col1 int );
drop table ack;
create table ack ( colA char( 1 ) );
drop table ack;
end;
Run Code Online (Sandbox Code Playgroud)
……成功了。上面的原始 proc 尝试也是如此。所以...
TempDB与用户数据库相比,对象的对象名称保留有什么区别(以及为什么存在)。我查看过的 Logical Query Processing 参考资料和 DDL 命令参考资料似乎都没有解释这一点。
这与 TempDB 中的对象名称保留无关,也与运行时无关。这只是解析器无法遵循逻辑或代码路径,以确保您的代码不可能尝试两次创建该表。请注意,如果您只单击 Parse 按钮 ( Ctrl+ F5) ,您会得到完全相同的(非运行时!)错误。基本上,如果你有这个:
IF 1=1
CREATE TABLE #foo(id1 INT);
ELSE
CREATE TABLE #foo(id2 INT);
Run Code Online (Sandbox Code Playgroud)
解析器看到这个:
CREATE TABLE #foo(id1 INT);
CREATE TABLE #foo(id2 INT);
Run Code Online (Sandbox Code Playgroud)
为什么它不适用于实际表,包括在 TempDB 中创建的实际用户表(请注意,它也不是特定于数据库的)?我可以建议的唯一答案是解析器对 #temp 表有一组不同的规则(也有很多其他差异)。如果你想要更具体的原因,你需要向微软开一个案例,看看他们是否会给你更多的细节。我猜你会被告知:“这就是它的工作方式。”
这些答案中的更多信息:
| 归档时间: |
|
| 查看次数: |
511 次 |
| 最近记录: |