Tag Archive constraint

Byphunsanit

MSSQL: alter table set compound unique constraint

เป็น SQL Server script ที่ค้นหา compound PK (Primary Key) และ FK (Foreign Key) ให้จากนั้นสร้าง UQ (Unique Constraint) โดยการ alter นอกจากนั้นยังหา unique index ที่ซ้ำซ้อนเพราะเวลาสร้าง Unique Constraint (UQ) SQL Server จะสร้าง Unique Index (ดัชนีแบบ Unique) ขึ้นมาให้โดยอัตโนมัติสร้าง UQ แล้วให้เอง ทำให้ควรลบของเก่าออกไป เพื่อที่จะลดการใช้ทรัพยากรณ์
alter_table_set_compound_unique_keys.sql

SELECT
    SCHEMA_NAME(t.schema_id) AS SchemaName,
    t.name AS TableName,
    i.name AS IndexName,
    COUNT(ic.column_id) AS ColumnCount,
    STRING_AGG(c.name, ', ') WITHIN GROUP (ORDER BY ic.key_ordinal) AS Columns,

    -- COLUMN 1 (Your Request): Adds a UQ *in addition* to the old index
    N'ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(t.name) +
    N' ADD CONSTRAINT ' + QUOTENAME(N'UQ_' + i.name) +  -- Naming convention: UQ_<OldIndexName>
    N' UNIQUE (' +
    STRING_AGG(QUOTENAME(c.name), N', ') WITHIN GROUP (ORDER BY ic.key_ordinal) +
    N');' AS Add_UQ_Script,

    -- COLUMN 2 (Recommended): *Replaces* the old index with a UQ
    N'DROP INDEX ' + QUOTENAME(i.name) + N' ON ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(t.name) + N';' +
    N' ALTER TABLE ' + QUOTENAME(SCHEMA_NAME(t.schema_id)) + N'.' + QUOTENAME(t.name) +
    N' ADD CONSTRAINT ' + QUOTENAME(N'UQ_' + i.name) +
    N' UNIQUE (' +
    STRING_AGG(QUOTENAME(c.name), N', ') WITHIN GROUP (ORDER BY ic.key_ordinal) +
    N');' AS Replace_With_UQ_Script
FROM
    sys.indexes AS i
JOIN
    sys.tables AS t ON i.object_id = t.object_id
JOIN
    sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
JOIN
    sys.columns AS c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
WHERE
    i.is_unique = 0         -- Filter for NON-unique indexes
    AND i.is_primary_key = 0  -- Exclude Primary Keys
    AND i.type_desc != 'HEAP'
GROUP BY
    SCHEMA_NAME(t.schema_id),
    t.name,
    i.name
HAVING
    COUNT(ic.column_id) > 1  -- Find only those with more than one column
ORDER BY
    SchemaName,
    TableName;