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สคีมา

เป็นพฤติกรรมที่คาดหวังหรือไม่ ฉันรู้ว่านี่เป็นกรณีที่เกิดขึ้นแน่นอนเกี่ยวกับการใช้ตาราง temp เฉพาะ schema อย่างไรก็ตามมันจะดีถ้าเอ็นจิ้นมีข้อผิดพลาดเมื่อพยายามสร้างตารางชั่วคราวที่ผูกกับสคีมาหรือจริง ๆ แล้วผูกกับสคีมาที่ระบุใน DDL

นอกจากนี้ฉันไม่สามารถเข้าถึง SQL Server 2014 หรือ 2016 ได้ในขณะนี้ มันทำงานได้ตามที่คาดหวังในแพลตฟอร์มเหล่านั้นหรือไม่


ชุดการฝึกอบรมสำหรับ 70-461 ระบุว่า 'สร้างตารางชั่วคราวใน tempdb ใน dbo schema' แต่จะไม่เข้าไปในข้อมูลใด ๆ มากกว่านั้นดังนั้นฉันไม่แน่ใจว่ามันจะมีความหมายเฉพาะเมื่อคุณไม่ ' ไม่ระบุสคีมา
Mark Sinkinson

คำตอบ:


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 แน่นอน)
เคนเน็ ธ ฟิชเชอร์

ดังนั้นจึงมีรหัสที่ละเว้นชื่อสกีมาอย่างชัดเจนเมื่อสร้างตารางชั่วคราว และรหัสนั้นเงียบ
Max Vernon
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.