CREATE TABLE SomeSchema.#TempTableName 有错误吗?

Han*_*non 12 sql-server sql-server-2008-r2 sql-server-2012 tempdb

简单的试验台:

USE tempdb;
GO

/*
    This DROP TABLE should not be necessary, since the DROP SCHEMA
    should drop the table if it is contained within the schema, as
    I'd expect it to be.
*/
IF COALESCE(OBJECT_ID('tempdb..#MyTempTable'), 0) <> 0 
    DROP TABLE #MyTempTable;

IF EXISTS (SELECT 1 FROM sys.schemas s WHERE s.name = 'SomeSchema') 
    DROP SCHEMA SomeSchema;
GO

CREATE SCHEMA SomeSchema AUTHORIZATION [dbo]
CREATE TABLE SomeSchema.#MyTempTable /* specifying the schema
                                        should not be necesssary since
                                        this statement is executed inside
                                        the context of the CREATE SCHEMA
                                        statement
                                     */
(
    TempTableID INT NOT NULL IDENTITY(1,1)
    , SomeData VARCHAR(50) NOT NULL
);
GO

INSERT INTO tempdb.SomeSchema.#MyTempTable (SomeData) VALUES ('This is a test');

SELECT *
FROM tempdb.SomeSchema.#MyTempTable;
GO

SELECT *
FROM sys.objects o
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE s.name = 'SomeSchema';

SELECT s.name
    , o.name
FROM sys.objects o
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
WHERE s.name = 'dbo'
    AND o.name LIKE '%MyTempTable%';

DROP SCHEMA SomeSchema;
DROP TABLE #MyTempTable;
Run Code Online (Sandbox Code Playgroud)

上面应该#MyTempTable在名为SomeSchema;的模式下的 tempdb 中创建一个名为的临时表;然而事实并非如此。相反,该表是在dbo架构中创建的。

这是预期的行为吗?我意识到这肯定是使用特定于架构的临时表的边缘情况;但是,如果引擎在尝试创建模式绑定临时表时提供错误,或者确实将其绑定到 DDL 中指定的模式,那就太好了。

此外,我目前无法访问 SQL Server 2014 或 2016;它在这些平台上是否按预期工作?

Aar*_*and 11

两个引用都是有效的并且可以正确解析,但 #temp 表是在dbo架构下创建的。

相同的答案(在你的系统上,一些我猜不到的数字):

SELECT OBJECT_ID('dbo.#MyTempTable');
SELECT OBJECT_ID('SomeSchema.#MyTempTable');
Run Code Online (Sandbox Code Playgroud)

相同的答案(均为 1,即dbo):

SELECT schema_id FROM sys.tables WHERE [object_id] = OBJECT_ID('dbo.#MyTempTable');
SELECT schema_id FROM sys.tables WHERE [object_id] = OBJECT_ID('SomeSchema.#MyTempTable');
Run Code Online (Sandbox Code Playgroud)

能够指定模式不会给您带来任何好处,因为您不会在会话中发生冲突(不同模式下的两个同名 #temp 表),对吧?

这是预期的行为。#temp 表与会话相关联,但与特定架构无关。它一直工作到 2016 CTP 3.2。解析器可能是宽容的,允许无意义的模式名称与允许这种错误的尾随逗号大致相同:

CREATE TABLE dbo.foo 
(
        bar INT
        ,
);
Run Code Online (Sandbox Code Playgroud)