我在我的數據庫中創建了幾個表類型,用作存儲過程參數。這些對應於真正的數據庫表,所以如果它們不同步,就會出現問題。我想添加一個單元測試,看看這兩者,如果它們不同,就會失敗,但我不確定從哪裏開始。驗證表類型是否正確來自C#
我不知道是否有推薦的方法來做到這一點 - 我會試圖以某種方式拉出列信息,循環通過它,並通過測試,如果他們不同,但似乎有點fiddly 。
有沒有更好的方法?
我在我的數據庫中創建了幾個表類型,用作存儲過程參數。這些對應於真正的數據庫表,所以如果它們不同步,就會出現問題。我想添加一個單元測試,看看這兩者,如果它們不同,就會失敗,但我不確定從哪裏開始。驗證表類型是否正確來自C#
我不知道是否有推薦的方法來做到這一點 - 我會試圖以某種方式拉出列信息,循環通過它,並通過測試,如果他們不同,但似乎有點fiddly 。
有沒有更好的方法?
對於SQL Server 2008,看看在sys.tables
,sys.table_types
和sys.columns
系統表。
在我的數據庫之一,我有一個表類型,稱爲candidateRoutes
和物理(實際)表稱爲RouteArea
以下兩個查詢:
select sys.columns.* from sys.table_types join sys.columns on sys.columns.object_id = sys.table_types.type_table_object_id where sys.table_types.name = 'candidateRoutes'
select sys.columns.* from sys.tables join sys.columns on sys.columns.object_id = sys.tables.object_id where sys.tables.name = 'RouteArea'
回報:
object_id name column_id system_type_id user_type_id max_length precision scale collation_name is_nullable is_ansi_padded is_rowguidcol is_identity is_computed is_filestream is_replicated is_non_sql_subscribed is_merge_published is_dts_replicated is_xml_document xml_collection_id default_object_id rule_object_id is_sparse is_column_set
215671816 RouteId 1 56 56 4 10 0 NULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
215671816 Area 2 240 130 -1 0 0 NULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
和
object_id name column_id system_type_id user_type_id max_length precision scale collation_name is_nullable is_ansi_padded is_rowguidcol is_identity is_computed is_filestream is_replicated is_non_sql_subscribed is_merge_published is_dts_replicated is_xml_document xml_collection_id default_object_id rule_object_id is_sparse is_column_set
1675153013 RouteId 1 127 127 8 19 0 NULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1675153013 ValidFrom 2 61 61 8 23 3 NULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1675153013 ValidTo 3 61 61 8 23 3 NULL 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1675153013 Line 4 240 130 -1 0 0 NULL 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1675153013 Area 5 240 130 -1 0 0 NULL 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
,所以你也許可以做這樣的事情:
with
TableType as
(select name, user_type_id, max_length, precision from sys.columns where object_id = (select type_table_object_id from sys.table_types where name = 'candidateRoutes')),
PhysicalTable as
(select name, user_type_id, max_length, precision from sys.columns where object_id = (select object_id from sys.tables where name = 'RouteArea'))
select * from TableType full join PhysicalTable
on TableType.name = PhysicalTable.name
where TableType.name is null
or PhysicalTable.name is null
or TableType.user_type_id <> PhysicalTable.user_type_id
or TableType.max_length <> PhysicalTable.max_length
or TableType.precision <> PhysicalTable.precision
但包括scale, collation_name, is_nullable
等,發現做不匹配的所有列。在我的情況下,我得到:
name user_type_id max_length precision name user_type_id max_length precision
RouteId 56 4 10 RouteId 127 8 19
NULL NULL NULL NULL ValidFrom 61 8 23
NULL NULL NULL NULL ValidTo 61 8 23
NULL NULL NULL NULL Line 130 -1 0
如果沒有行返回,類型和表是相同的。
謝謝Gavin。你的最後一個查詢的where子句 - 爲什麼'where TableType.name是null ...'?如果任何列都有名字,是不是返回0行?看起來像是我想要的第一步,儘管 – Alex 2011-05-20 08:55:51
@Alex:我在'TableType'和'PhysicalTable'上做了一個'full join',這樣就可以顯示'TableType'中存在的所有列名稱,即使'PhysicalTable'中沒有相應的列,反之亦然。這兩個檢查'名稱是空',然後將結果限制爲只存在於一個表或另一個表中的列。例如,'PhysicalFrom'存在於'PhysicalTable'中,但'TableType'中不存在,因此'TableType.name'爲null。如果在where子句中只使用這兩個條件,則基本上可以看到任何一個表中存在的所有列,但在另一個表中卻缺失了其他條件... – 2011-05-23 12:10:02
... where子句中的其餘條件包括_both_表中存在的所有列,但有不同的類型。 – 2011-05-23 12:10:40
就像你說的那樣,用C#,你必須將兩個表中的數據轉儲到不同的DataSet中,然後循環和比較。如果你有成千上萬的記錄,那麼這將是一個巨大的資源浪費,並且很可能會產生非常不理想的表現。
你必須在C#中完成嗎?你爲什麼不在SQL中進行比較並返回一個結果布爾(如果一切都是一樣的,如果有差異則返回false)?
但是,如果你必須在.NET中做到這一點,你試過看着F#嗎?我一直在做一些閱讀,看起來F#可能是C#之上的一種性能改進,用於這種數據分析。
這裏有一篇文章可以幫助你處理F#和SQL。或者,你可以看看LINQ(對不起,我對它沒有經驗),它可能是你正在尋找的東西的答案。 http://www.linqpad.net/WhyLINQBeatsSQL.aspx
+1既然你和Gavin建議,我試圖創建一個存儲過程將在SQL服務器上運行,然後將成功/失敗返回給我的C#代碼 – Alex 2011-05-24 09:10:40
對不起,表格類型是什麼意思? 您是否在比較數據庫中的兩個表? 或者你是否試圖比較只存在於C#方面的數據? 或者您是否試圖將存在於C#上的一組數據與數據庫中存在的表進行比較? – Kukoy 2011-05-19 13:43:12
這是我在做什麼: CREATE TYPE MyTableType AS TABLE ([Column definitions ...]) 這是我的實際MyTable表的鏡像,我可以在批量更新中使用它作爲表值參數(http://msdn.microsoft.com/en-us/library/bb510489.aspx)。我想要做的是在C#中編寫一個測試,將MyTableType與MyTable逐列比較。我想這與比較兩個實際表格非常相似。 – Alex 2011-05-19 14:14:08
爲了澄清,你說的是表結構(列名和列類型),不一定是數據,對不對? – 2011-05-19 15:13:19