SQL Server數(shù)據(jù)庫(kù)中的表名稱、字段比較
前言
項(xiàng)目中一般分測(cè)試環(huán)境(QAS),生產(chǎn)環(huán)境(PRD),當(dāng)我們的項(xiàng)目經(jīng)歷了一次周期跨度較長(zhǎng)的更新后,當(dāng)我們發(fā)布到生產(chǎn)環(huán)境時(shí),首要的任務(wù)是將新增的表,字段更新到生產(chǎn)數(shù)據(jù)庫(kù)。很多時(shí)候,當(dāng)我們發(fā)布更新的時(shí)候,已經(jīng)很難記得做了哪些變更。
當(dāng)然有的人會(huì)說(shuō),1.EF Code First 有history記錄,這是一種辦法,可靠么?不可靠。相信即便是用Code First,直接改數(shù)據(jù)庫(kù)的肯定不止我一個(gè)。
2.查看實(shí)體類變更記錄,這也是一個(gè)辦法。那如果用的DB First的呢?當(dāng)然也可以看,就是很麻煩。
3.開(kāi)發(fā)過(guò)程中,對(duì)數(shù)據(jù)庫(kù)的變更記下來(lái)。這么做過(guò)的肯定也不止我一個(gè)。手動(dòng)狗頭
。。。。。
中午的時(shí)候,就想著另外一個(gè)項(xiàng)目下個(gè)月要更新,改了N多的東西,到時(shí)候數(shù)據(jù)庫(kù)咋更新呢。就想著寫(xiě)個(gè)工具比較兩個(gè)版本數(shù)據(jù)庫(kù),表名稱,字段,字段類型的區(qū)別。
說(shuō)干就干(本來(lái)想著用EF,DBContext應(yīng)該可以實(shí)現(xiàn),無(wú)奈學(xué)藝不精,最終還是回到了ADO.Net)。
控制臺(tái)應(yīng)用程序,目前只能對(duì)比新增,修改(SQl Server)。
using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using Microsoft.EntityFrameworkCore; namespace EFGetTable { class Program { static void Main(string[] args) { string prdconnectionstring = "Data Source=localhost;initial catalog=ttPRD;user id=sa;password=password;MultipleActiveResultSets=True"; var prd = GetTableNames(prdconnectionstring); string qasconnectionstring = "Data Source=localhost;initial catalog=ttqas;user id=sa;password=password;MultipleActiveResultSets=True"; var qas = GetTableNames(qasconnectionstring); CompareTable(prd, qas); } public static List<TableInfo> GetTableNames(string connectionstr) { var tableresult = new List<TableInfo>(); string sqlTableName = "Select * From Information_Schema.Tables"; using (SqlConnection connection = new SqlConnection(connectionstr)) { using (SqlCommand cmd = new SqlCommand(sqlTableName, connection)) { try { connection.Open(); SqlDataReader dr = cmd.ExecuteReader();// while (dr.Read()) { // 表名 TableInfo table = new TableInfo(); table.TableName = dr["Table_Name"].ToString(); table.columns.AddRange(GetColumnNamesByTable(dr["Table_Name"].ToString(), connection)); tableresult.Add(table); } connection.Close(); } catch (System.Data.SqlClient.SqlException e) { Console.ForegroundColor = ConsoleColor.Red; Console.Error.WriteLine(e.Message); connection.Close(); } } return tableresult; } } public static List<CloumnInfo> GetColumnNamesByTable(string tableName, SqlConnection connection) { var Columnresults = new List<CloumnInfo>(); string sqlcolum = $"Select * From Information_Schema.Columns t Where t.Table_Name =\'{tableName}\'"; using (SqlCommand cmd = new SqlCommand(sqlcolum, connection)) { SqlDataReader dr = cmd.ExecuteReader();// while (dr.Read()) { // 表名 CloumnInfo column = new CloumnInfo(); column.CloumnName = dr["Column_name"].ToString(); column.DateType = dr["DATA_TYPE"].ToString() + dr["CHARACTER_MAXIMUM_LENGTH"].ToString(); Columnresults.Add(column); } return Columnresults; } } public static void CompareTable(List<TableInfo> prd, List<TableInfo> qas) { foreach (var p in qas) { var tablequery = prd.AsQueryable().Where(t => t.TableName.Equals(p.TableName)); if (!tablequery.Any()) { Console.WriteLine($"New Created Table {p.TableName}"); continue; } else { var querytable = tablequery.FirstOrDefault(); p.columns.ForEach(c => { var Cloumnquery = querytable.columns.Select(cc => cc.CloumnName).Contains(c.CloumnName); if (!Cloumnquery) { Console.WriteLine($"New add cloumn: {c.CloumnName} on Table {p.TableName}"); } else { var querycloumn = querytable.columns.Where(qt => qt.CloumnName.Equals(c.CloumnName)).FirstOrDefault(); if (!querycloumn.DateType.Equals(c.DateType)) { Console.WriteLine($"DateType Different: cloumn: {c.CloumnName} , {querycloumn.DateType}==>{c.DateType} on Table {p.TableName}"); } } }); } } } } public class TableInfo { public TableInfo() { columns = new List<CloumnInfo>(); } public string TableName { get; set; } public List<CloumnInfo> columns { get; set; } } public class CloumnInfo { public string CloumnName { get; set; } public string DateType { get; set; } } }
測(cè)試結(jié)果
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- 圖書(shū)管理系統(tǒng)的sqlserver數(shù)據(jù)庫(kù)設(shè)計(jì)示例
- sql server數(shù)據(jù)庫(kù)中raiserror函數(shù)用法的詳細(xì)介紹
- SQL Server數(shù)據(jù)庫(kù)錯(cuò)誤5123解決方案
- SqlServer數(shù)據(jù)庫(kù)中文亂碼問(wèn)題解決方法
- SQL Server免費(fèi)版的安裝以及使用SQL Server Management Studio(SSMS)連接數(shù)據(jù)庫(kù)的圖文方法
- SQL Server 2000/2005/2008刪除或壓縮數(shù)據(jù)庫(kù)日志的方法
- SQLServer數(shù)據(jù)庫(kù)處于恢復(fù)掛起狀態(tài)的解決辦法
- Servermanager啟動(dòng)連接數(shù)據(jù)庫(kù)錯(cuò)誤如何解決
相關(guān)文章
深入sql server 2005 萬(wàn)能分頁(yè)存儲(chǔ)過(guò)程的詳解
本篇文章是對(duì)sqlserver2005中的萬(wàn)能分頁(yè)存儲(chǔ)過(guò)程進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06sql server通過(guò)腳本進(jìn)行數(shù)據(jù)庫(kù)壓縮全備份的方法【推薦】
這篇文章主要介紹了sql server通過(guò)腳本進(jìn)行數(shù)據(jù)庫(kù)壓縮全備份的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06用SQL語(yǔ)句添加刪除修改字段、一些表與字段的基本操作、數(shù)據(jù)庫(kù)備份等
用SQL語(yǔ)句添加刪除修改字段、一些表與字段的基本操作、數(shù)據(jù)庫(kù)備份等,需要的朋友可以參考下。2011-11-11SQLServer 附加數(shù)據(jù)庫(kù)后出現(xiàn)只讀或失敗的解決方法
如果你在附加SQL數(shù)據(jù)庫(kù),出現(xiàn)只讀或失敗的情況,來(lái)看下本文的解決方案吧。2010-03-03必須會(huì)的SQL語(yǔ)句(八) 數(shù)據(jù)庫(kù)的完整性約束
這篇文章主要介紹了sqlserver中數(shù)據(jù)庫(kù)的完整性約束使用方法,需要的朋友可以參考下2015-01-01SQL?SERVER常用的日期與時(shí)間查詢總結(jié)
這篇文章介紹了SQL?SERVER常用日期與時(shí)間查詢的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04sql 游標(biāo)的使用—游標(biāo)FOR循環(huán)小例子
游標(biāo)for循環(huán)是在pl/sql塊中使用游標(biāo)最簡(jiǎn)單的方式,它簡(jiǎn)化了對(duì)游標(biāo)的處理。當(dāng)使用游標(biāo)for循環(huán)時(shí),oracle會(huì)隱含的打開(kāi)游標(biāo),提取游標(biāo)數(shù)據(jù)并關(guān)閉游標(biāo)。2013-05-05參考sql2012存儲(chǔ)過(guò)程寫(xiě)的統(tǒng)計(jì)所有用戶表尺寸大小的示例
參考SQL2005, 2008和2012的系統(tǒng)存儲(chǔ)過(guò)程master.sys.sp_spaceused代碼后,寫(xiě)了下面一條語(yǔ)句來(lái)方便平時(shí)統(tǒng)計(jì)所有用戶表尺寸大小2014-01-01SQL Server學(xué)習(xí)筆記之事務(wù)、鎖定、阻塞、死鎖用法詳解
這篇文章主要介紹了SQL Server學(xué)習(xí)筆記之事務(wù)、鎖定、阻塞、死鎖用法,結(jié)合實(shí)例形式分析了SQL Server中事務(wù)、鎖定、阻塞、死鎖的概念、功能及相關(guān)使用技巧,需要的朋友可以參考下2017-07-07