web-dev-qa-db-fra.com

Create Table Someschema. # TemptableName a un bug?

Simple test-lit:

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;

Ce qui précède devrait créer une table temporaire nommée #MyTempTable Dans le TEMPDB sous le schéma nommé SomeSchema; Cependant, ce n'est pas le cas. Au lieu de cela, la table est créée dans le schéma dbo.

Est-ce que ce comportement attendu? Je me rends compte que c'est certainement un cas de bord autour de l'utilisation de tables temporaires spécifiques au schéma; Cependant, ce serait bien que le moteur a fourni une erreur lors de la tentative de création d'une table temporaire liée au schéma ou de la liaison réellement au schéma spécifié dans le DDL.

En outre, je n'ai pas actuellement accès à SQL Server 2014 ou 2016; Est-ce que cela fonctionne comme prévu sur ces plates-formes?

12
Max Vernon

Les deux références sont valides et vont résoudre correctement, mais la table #TEpp est créée sous le schéma dbo.

Même réponse (sur votre système, un nombre que je ne pouvais pas deviner):

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

Même réponse (les deux 1, qui est 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');

Être capable de spécifier un schéma ne vous achète rien parce que vous n'allez pas avoir de collisions (deux tables #TEMP de même noms sous différents schémas) au cours d'une session, non?

Ceci est attendu comportement. Une table #TEpp est liée à une session, mais pas à un schéma spécifique. Et cela fonctionne de la même manière jusqu'à 2016 CTP 3.2. L'analyseur est probablement pardonnant, permettant au nom de schéma sans signification de la même manière qu'elle permet à cette virgule de suivi errant:

CREATE TABLE dbo.foo 
(
        bar INT
        ,
);
11
Aaron Bertrand