在寫代碼生成器的時候遇到這樣一個問題,想在搭建好數據庫后把字段說明當做注釋寫進類文件里,所以我們在網上搜索到了許多代碼很長很長的方法(當然我的代碼也很長),親測了一條簡單易懂的語句,也是大多數轉載的方法:
SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Description = ex.value, ColumnType=t.name, Length=c.max_length FROM sys.columns c LEFT OUTER JOIN sys.extended_properties ex ON ex.major_id = c.object_id AND ex.minor_id = c.column_id AND ex.name = 'MS_Description' left outer join systypes t on c.system_type_id=t.xtype WHERE OBJECTPROPERTY(c.object_id, 'IsMsShipped')=0 AND OBJECT_NAME(c.object_id) ='表名'
親測可用沒問題,但是在測試的時候出現這樣一個問題
我的表中的確是有Title 和Category字段,但是為什么查出來的結果有兩條呢?
看ColumnType 不難理解,這兩個一個是我自己的表中的字段,另一個是系統保留字段, 那么問題又回到了我最初使用的語句:
select COLUMN_NAME,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH from information_schema.columns where TABLE_NAME='表名'
這樣一來查詢結果是這樣的:
結果中整形和ntext類型是我不需要長度的類型,結果是NULL正合我意,但是這里沒有我要的字段說明。所以我打算兩個語句結合起來試一下,在這之前我們需要了解一下第一個查詢語句中有哪些是我們需要的。
於是我分別嘗試了查詢以下3個表的內容,為了解它的結構。我們看到
select * from sys.extended_properties select * from information_schema.columns select * from sys.columns
首先是select * from sys.extended_properties
結果如下:
那么所有的表的描述都在這里了
然后我們再來看
select * from information_schema.columns
select * from sys.columns
這兩張表里面內容很多,這里就不截圖了,大家可以自己查一下看看內容。
經過比較以后得出結論:在我們最先搜索到的方法中OBJECT_NAME(c.object_id)是將sys.columns中的object_id轉換成表名的方法,但是sys.columns中沒有我們需要的信息,所以OBJECT_NAME()方法留着備用;
其次我們在上一個截圖中sys.extended_properties表看到了major_id這個字段,這個字段有什么含義?於是我從sys.columns查詢了一下sys.columns.object_id=sys.extended_properties.major_id的內容,比如上述截圖中的
select * from sys.columns where object_id=613577224
得到的結果正好是同一張表中的字段信息,於是得出結論:
表sys.extended_properties中的major_id和sys.columns中object_id是相關聯的(主鍵外鍵關系?)
終於我們找到了sys.extended_properties表和information_schema.columns表中共有的字段,那就是:
sys.extended_properties.major_id和information_schema.columns.TABLE_NAME
因為sys.columns.object_id就是sys.extended_properties.major_id 那么OBJECT_NAME(sys.extended_properties.major_id)=information_schema.columns.TABLE_NAME就是架起兩者之間關系的橋梁了
說了一堆廢話,看最終的語句:
select a.COLUMN_NAME,a.DATA_TYPE,a.CHARACTER_MAXIMUM_LENGTH,b.value from information_schema.COLUMNS as a left join sys.extended_properties as b on a.TABLE_NAME=OBJECT_NAME(b.major_id) and a.ORDINAL_POSITION=b.minor_id where a.TABLE_NAME='表名'
結果:
這樣只需要在代碼中判斷NULL字段就可以了!