Чи 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;

Вищезазначене повинно створити тимчасову таблицю з ім'ям #MyTempTabletempdb за схемою з назвою SomeSchema; однак це не так. Натомість таблиця створюється у dboсхемі.

Це очікувана поведінка? Я розумію, що це, безумовно, кращий випадок навколо використання темп-таблиць, характерних для схеми; однак було б непогано, якби двигун або створив помилку при спробі створення тимчасової таблиці, пов'язаної зі схемою, або насправді прив’язав її до схеми, зазначеної в DDL.

Також в даний час у мене немає доступу до SQL Server 2014 або 2016; чи працює це так, як очікувалося на цих платформах?


Навчальний комплект для 70-461 зазначає, що "Тимчасові таблиці створюються в tempdb в схемі dbo.", Однак це більше не входить в цю інформацію, тому я не впевнений, чи означає це лише тоді, коли ви цього не зробите " t вкажіть схему.
Марк Сінкінсон

Відповіді:


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
        ,
);

Ймовірно, значною мірою тому, що тимчасові таблиці фактично створені в TempDB, і локальна схема не працює (якщо ви, звичайно, не були в TempDB, звичайно)
Кеннет Фішер,

Отже, чітко існує код, який ігнорує ім'я схеми під час створення тимчасової таблиці; і цей код мовчить.
Макс Вернон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.