CREATE TABLE someSchema. # TempTableName có lỗi không?


12

Giường thử đơn giản:

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;

Ở trên sẽ tạo một bảng tạm thời có tên #MyTempTabletrong tempdb dưới lược đồ có tên SomeSchema; tuy nhiên nó không. Thay vào đó, bảng được tạo trong dbolược đồ.

Đây có phải là hành vi dự kiến? Tôi nhận ra rằng đây chắc chắn là một trường hợp cạnh xung quanh việc sử dụng các bảng tạm thời dành riêng cho lược đồ; tuy nhiên, sẽ rất tuyệt nếu công cụ cung cấp lỗi khi cố gắng tạo bảng tạm thời ràng buộc lược đồ hoặc thực sự đã liên kết nó với lược đồ được chỉ định trong DDL.

Ngoài ra, hiện tại tôi không có quyền truy cập vào SQL Server 2014 hoặc 2016; nó có hoạt động như mong đợi trên các nền tảng đó không?


Bộ công cụ đào tạo cho 70-461 nói rằng 'Các bảng tạm thời được tạo trong tempdb trong lược đồ dbo.', Tuy nhiên, nó không đi sâu vào bất kỳ thông tin nào hơn thế, vì vậy tôi không chắc điều đó chỉ có nghĩa khi bạn không ' t chỉ định một lược đồ.
Mark Sinkinson

Câu trả lời:


11

Cả hai tham chiếu đều hợp lệ và sẽ giải quyết chính xác, nhưng bảng #temp được tạo theo dbolược đồ.

Cùng một câu trả lời (trên hệ thống của bạn, một số số tôi không thể đoán được):

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

Cùng một câu trả lời (cả 1, đó là 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');

Có thể chỉ định một lược đồ không mua cho bạn bất cứ thứ gì vì bạn sẽ không có xung đột (hai bảng #temp cùng tên dưới các lược đồ khác nhau) trong một phiên, phải không?

Đây là hành vi dự kiến. Bảng #temp được gắn với một phiên, nhưng không phải là một lược đồ cụ thể. Và nó hoạt động tương tự cho đến năm 2016 CTP 3.2. Trình phân tích cú pháp có thể được tha thứ, cho phép tên lược đồ vô nghĩa theo cách tương tự như nó cho phép dấu phẩy dấu vết sai lầm này:

CREATE TABLE dbo.foo 
(
        bar INT
        ,
);

Có lẽ phần lớn là do các bảng tạm thời thực sự được tạo trong TempDB và một lược đồ cục bộ sẽ không hoạt động (tất nhiên trừ khi bạn thực sự ở TempDB)
Kenneth Fisher

Vì vậy, rõ ràng có mã bỏ qua tên lược đồ khi tạo bảng tạm thời; và mã đó là im lặng.
Max Vernon
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.