CREATE TABLE SomeSchema。#TempTableName是否存在错误?


12

简单的测试台:

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;

上面的代码应该#MyTempTable在tempdb命名模式下创建一个临时表SomeSchema;但是事实并非如此。而是在dbo架构中创建表。

这是预期的行为吗?我意识到这肯定是使用特定于架构的临时表的一个极端情况。但是,如果引擎在尝试创建与模式绑定的临时表时提供了错误,或者实际上确实将其绑定到了DDL中指定的模式,那将是很好的选择。

另外,我目前无法访问SQL Server 2014或2016;在这些平台上可以正常工作吗?


针对70-461的培训套件指出“临时表是在dbo模式中的tempdb中创建的。”但是,它所包含的信息并不多,所以我不确定这是否仅意味着当您不这样做的时候”指定模式。
Mark Sinkinson '16

Answers:


11

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

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

SELECT OBJECT_ID('dbo.#MyTempTable');
SELECT OBJECT_ID('SomeSchema.#MyTempTable');

相同的答案(均为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');

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

这是预期的行为。#temp表绑定到会话,但不绑定到特定架构。直到2016年CTP 3.2,它的工作方式一直相同。解析器可能是原谅的,允许无意义的模式名称的方式与允许此错误的结尾逗号非常相似:

CREATE TABLE dbo.foo 
(
        bar INT
        ,
);

可能在很大程度上是因为temp表实际上是在TempDB中创建的,并且本地模式不起作用(除非您当然实际上是在TempDB中的)
Kenneth Fisher

因此,显然有一些代码在创建临时表时会忽略模式名称。该代码是无声的。
Max Vernon
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.