วิธีตรวจสอบการมีอยู่ของชนิดตารางที่ผู้ใช้กำหนดใน SQL Server 2008


164

ฉันมีประเภทตารางที่ผู้ใช้กำหนด ฉันต้องการตรวจสอบว่ามีอยู่จริงก่อนทำการแก้ไขในแพทช์โดยใช้OBJECT_ID(name, type)ฟังก์ชั่น

สิ่งtypeที่ควรจะส่งผ่านจากการแจงนับสำหรับประเภทตารางที่ผู้ใช้กำหนด?

N'U' เช่นสำหรับตารางที่ผู้ใช้กำหนดไม่ทำงานเช่น IF OBJECT_ID(N'MyType', N'U') IS NOT NULL

คำตอบ:


188

คุณสามารถดูใน sys.types หรือใช้ TYPE_ID:

IF TYPE_ID(N'MyType') IS NULL ...

ข้อควรระวัง: การใช้ type_id จะไม่ตรวจสอบว่าเป็นประเภทตารางหรือไม่โดยใช้ชื่อตามประเภทนั้น มิฉะนั้นคำค้นหาของ gbn น่าจะดีกว่า


ฉันพยายามอย่างไร้เดียงสาIF OBJECT_ID(N'MyType', 'TT') IS NULLโดยไม่ประสบความสำเร็จ แต่โซลูชันของคุณใช้ได้ผล
Allon Guralnek

1
การแจงนับ 'TT' ใช้งานได้ใน sql server 2012 หรือใหม่กว่าเท่านั้น (ตามที่ฉันเพิ่งค้นพบ)
Iain

3
@ ฉันมันยังไม่จริง คุณไม่สามารถใช้ OBJECT_ID เพื่อค้นหาประเภทตารางตามชื่อ - ตรวจสอบSELECT name FROM sys.objects WHERE type = 'TT'
NReilingh

109
IF EXISTS (SELECT * FROM sys.types WHERE is_table_type = 1 AND name = 'MyType')
    --stuff

sys.types ... พวกเขาไม่ได้เป็นวัตถุที่กำหนดขอบเขตคีมาดังนั้นจะไม่อยู่ในsys.objects

อัปเดต, Mar 2013

คุณสามารถใช้TYPE_ID ได้เช่นกัน


5
ฉันเชื่อว่าความคิดเห็นที่สองของคุณไม่ถูกต้อง หากฉันไม่เข้าใจผิดประเภทที่กำหนดโดยผู้ใช้นั้นเป็นแบบกำหนดขอบเขตแน่นอน ( Schema_IDจริง ๆ แล้วเป็นหนึ่งในแอตทริบิวต์ในตารางsys.types ที่คุณเชื่อมโยงด้วยนี่คือเหตุผลที่พวกเขาสามารถอ้างอิงได้ว่า [dbo] [myUDType] ) อย่างไรก็ตามคุณถูกต้องว่าประเภท UD ไม่ได้อยู่ใน sys.objects ดังนั้น OBJECT_ID จึงไม่สามารถเข้าถึงได้ (ไม่ว่าด้วยเหตุผลใด sys.objects ไม่ใช่รายชื่อวัตถุที่กำหนดขอบเขตแบบ schema)
kmote

1
@kmote - พวกเขาไม่ได้อยู่ในรายการsys.objectsโดยตรง แต่มีแถวที่นั่นสำหรับแต่ละเหล่านี้
Martin Smith

20
IF EXISTS(SELECT 1 FROM sys.types WHERE name = 'Person' AND is_table_type = 1 AND SCHEMA_ID('VAB') = schema_id)
DROP TYPE VAB.Person;
go
CREATE TYPE VAB.Person AS TABLE
(    PersonID               INT
    ,FirstName              VARCHAR(255)
    ,MiddleName             VARCHAR(255)
    ,LastName               VARCHAR(255)
    ,PreferredName          VARCHAR(255)
);

ฉันคิดว่านี่เป็นคำตอบที่สมบูรณ์ยิ่งขึ้นเนื่องจากตรวจสอบสคีมาด้วย
ฮามิดเฮย์ดาเรียน

6

ตัวอย่างต่อไปนี้ใช้ได้กับฉันโปรดทราบว่า "is_user_defined" NOT "is_table_type"

IF TYPE_ID(N'idType') IS NULL
CREATE TYPE [dbo].[idType] FROM Bigint NOT NULL
go

IF not EXISTS (SELECT * FROM sys.types WHERE is_user_defined = 1 AND name = 'idType')
CREATE TYPE [dbo].[idType] FROM Bigint NOT NULL
go

4

คุณสามารถใช้มุมมอง table_type ของระบบได้เช่นกัน

IF EXISTS (SELECT *
           FROM   [sys].[table_types]
           WHERE  user_type_id = Type_id(N'[dbo].[UdTableType]'))
  BEGIN
      PRINT 'EXISTS'
  END 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.