2 minute read

How to get SQL Server properties that are not in the information schema.

Overview

There are times when you need to extend the information schema columns. One example is obtaining the column id, as opposed to getting the ordinal position.

We can get the column id by using the COLUMNPROPERTY function. This takes three arguments: the object id, the column name, and the property wanted.

For example, we can demonstrate that the column id is a permanent reference, while the ordinal position can change after DDL operations.

1 - Build the test table:


CREATE TABLE test.testable ( 
    testable_seqn int identity not null, 
    testable_code varchar(50) not null, 
    testable_name varchar(50) not null, 
    testable_desc varchar(255) null 
) ; 
GO 

While the table is in a pristine state, if we query the information schema columns, we will find the Column ID and Ordinal Position are identical.

2 - Query Column Info:


SELECT 

    isc.TABLE_CATALOG 
    ,isc.TABLE_SCHEMA 
    ,isc.TABLE_NAME 
    ,isc.COLUMN_NAME 
    ,isc.ORDINAL_POSITION 
    ,COLUMN_ID = COLUMNPROPERTY(
        OBJECT_ID(isc.TABLE_SCHEMA + CHAR(46) + isc.TABLE_NAME) 
        ,isc.COLUMN_NAME 
        ,'ColumnID'  
    ) 

FROM INFORMATION_SCHEMA.COLUMNS as isc 

WHERE isc.TABLE_SCHEMA = 'test' 
    AND isc.TABLE_NAME = 'testable' 

ORDER BY isc.ORDINAL_POSITION 
; 
GO 

3 Inspect Results:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_ID
DataHub test testable testable_seqn 1 1
DataHub test testable testable_code 2 2
DataHub test testable testable_name 3 3
DataHub test testable testable_desc 4 4

4 - Remove a column:


ALTER TABLE test.testable 
DROP COLUMN testable_code 
; 
GO 

5 - Re-query column info:


SELECT 

    isc.TABLE_CATALOG 
    ,isc.TABLE_SCHEMA 
    ,isc.TABLE_NAME 
    ,isc.COLUMN_NAME 
    ,isc.ORDINAL_POSITION 
    ,COLUMN_ID = COLUMNPROPERTY(
        OBJECT_ID(isc.TABLE_SCHEMA + CHAR(46) + isc.TABLE_NAME) 
        ,isc.COLUMN_NAME 
        ,'ColumnID'  
    )

FROM INFORMATION_SCHEMA.COLUMNS as isc 

WHERE isc.TABLE_SCHEMA = 'test' 
    AND isc.TABLE_NAME = 'testable' 

ORDER BY isc.ORDINAL_POSITION 
; 
GO 

6 - Inspect Results:

TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_ID
DataHub test testable testable_seqn 1 1
DataHub test testable testable_name 2 3
DataHub test testable testable_desc 3 4

In short, the column id remained fixed, while the ordinal position updated to reflect the changing table structure.

The trick in the question

In SQL Server, the information schema views are derived from the system views.

Examine the object definition of information schema columns:


SELECT OBJECT_DEFINITION( OBJECT_ID('INFORMATION_SCHEMA.COLUMNS') ) 

Inspect the definition of ordinal position:


SELECT 

    COLUMNPROPERTY(c.object_id, c.name, 'ordinal')  AS ORDINAL_POSITION 

FROM sys.objects o 

    JOIN sys.columns c 
    ON c.object_id = o.object_id   

    LEFT JOIN sys.types t 
    ON c.user_type_id = t.user_type_id  

WHERE o.type IN ('U', 'V')  
; 

Both ordinal position and column id are derived from applying the column property function to the sys columns table.

QED

© Adam Heinz

22 April 2023

Categories:

Updated: