간단한 테스트 베드 :
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;
위의 이름 으로 스키마 아래에 tempdb 라는 임시 테이블을 작성 해야합니다 . 그러나 그렇지 않습니다. 대신 테이블이 스키마에 작성됩니다 . #MyTempTable
SomeSchema
dbo
이것이 예상되는 동작입니까? 필자는 이것이 스키마 별 임시 테이블 사용과 관련하여 확실한 사례라는 것을 알고 있습니다. 그러나 스키마 바인딩 된 임시 테이블을 만들려고 할 때 엔진에 오류가 발생했거나 실제로 DDL에 지정된 스키마에 바인딩하면 좋을 것입니다.
또한 현재 SQL Server 2014 또는 2016에 액세스 할 수 없습니다. 해당 플랫폼에서 예상대로 작동합니까?
답변
두 참조 모두 유효하고 올바르게 해석되지만 #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 테이블 2 개가 충돌하지 않기 때문에 아무것도 사지 않습니까?
이것은 예상 된 동작입니다. #temp 테이블은 세션에 연결되지만 특정 스키마에는 연결되지 않습니다. 그리고 2016 CTP 3.2까지 동일하게 작동합니다. 파서는 아마도 용서할 수 있으며,이 잘못된 후행 쉼표를 허용하는 것과 거의 같은 방식으로 의미없는 스키마 이름을 허용합니다.
CREATE TABLE dbo.foo
(
bar INT
,
);