国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > .NET > 正文

.Net中刪除數(shù)據(jù)前進(jìn)行外鍵沖突檢測(cè)

2024-07-10 13:01:38
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
在編寫(xiě)數(shù)據(jù)庫(kù)系統(tǒng)中為了保證系統(tǒng)中數(shù)據(jù)的一致性最簡(jiǎn)便且安全的方法就是在dbms中建立外鍵約束,但刪除主鍵數(shù)據(jù)時(shí)如果違反了外鍵約束,盡管dbms會(huì)給出錯(cuò)誤提示,如sql server的提示信息“%1! 語(yǔ)句與 %2! %3! 約束 '%4!' 沖突。該沖突發(fā)生于數(shù)據(jù)庫(kù) '%6!',表 '%8!'%10!%11!%13!。”,但這些提示信息對(duì)最終用戶(hù)來(lái)說(shuō),是不友好的,于是就自己寫(xiě)了個(gè)類(lèi),用來(lái)刪除記錄時(shí)的進(jìn)行外鍵沖突檢測(cè),代碼如下:

using system;
using system.data;
using system.data.sqlclient;
using microsoft.applicationblocks.data;

namespace dataaccess.sqlserverdal
{
///
/// check 的摘要說(shuō)明。
///
public class check
{
///
/// dbms中保存系統(tǒng)表的
///
const string default_systables = "systables";

#region ckeckfkbegindelete

///
/// 在刪除記錄之前先檢測(cè)有無(wú)外鍵沖突
///
/// 事物對(duì)象
/// 要執(zhí)行刪除操作的表名
/// 要?jiǎng)h除的記錄的主鍵值
/// 返回錯(cuò)誤信息
/// true - 無(wú)沖突,false - 有沖突
public bool ckeckfkbegindelete(sqltransaction trans, string tablename, string id, ref string errtext)
{
string selectstring; //sql查詢(xún)語(yǔ)句
string fktablename; //外鍵表名稱(chēng)
string fkcolumnname; //外鍵列名稱(chēng)
object obj; //執(zhí)行sql查詢(xún)返回值
string description; //外鍵表含義

int count; //外鍵表中引用了主鍵的記錄數(shù)

string[] tablenames = {"sysforeignkeys"};

dataset ds = builddatatables();

//檢索所有此表的外鍵表
selectstring = "select fkeyid, fkey from sysforeignkeys a, sysobjects b where a.rkeyid = b.id and b.name = @name";

sqlparameter name = new sqlparameter("@name", sqldbtype.varchar);
name.value = tablename;

sqlhelper.filldataset(trans, commandtype.text, selectstring, ds, tablenames, name);

//外鍵表id
sqlparameter id = new sqlparameter("@id", sqldbtype.int);
//外鍵列id
sqlparameter colid = new sqlparameter("@colid", sqldbtype.int);
//主鍵值
sqlparameter keyid = new sqlparameter("@keyid", sqldbtype.int);

//遍歷所有的外鍵表
foreach (datarow dr in ds.tables["sysforeignkeys"].rows)
{
//查詢(xún)外鍵表名稱(chēng)
selectstring = "select name from sysobjects where id = @id";
id.value = dr["fkeyid"];
fktablename = sqlhelper.executescalar(trans, commandtype.text, selectstring, id).tostring();

//查詢(xún)外鍵列名稱(chēng)
selectstring = "select name from syscolumns where id = @id and colid = @colid";
id.value = dr["fkeyid"];
colid.value = dr["fkey"];
fkcolumnname = sqlhelper.executescalar(trans, commandtype.text, selectstring, id, colid).tostring();

//查詢(xún)外鍵表中有沒(méi)有引用要?jiǎng)h除的主鍵
selectstring = "select count(*) from " + fktablename + " where " + fkcolumnname + " = @keyid";
keyid.value = id;
count = convert.toint32(sqlhelper.executescalar(trans, commandtype.text, selectstring, keyid));

if (count > 0)
{
//查詢(xún)發(fā)生沖突的表的含義,從而給用戶(hù)發(fā)出友好的提示
selectstring = "select description from callcentertables where tablename = @tablename";
sqlparameter tablename = new sqlparameter("@tablename", sqldbtype.varchar);
tablename.value = fktablename;

obj = sqlhelper.executescalar(trans, commandtype.text, selectstring, tablename);

if (obj != null)
description = obj.tostring();
else
description = fktablename;

errtext = "您要?jiǎng)h除的數(shù)據(jù)已在" + description + "中使用,要?jiǎng)h除該條數(shù)據(jù),請(qǐng)先刪除" +
description + "中的相關(guān)數(shù)據(jù),否則您將無(wú)法刪除此條記錄!";

return false;
}
}

return true;
}

#endregion

#region builddatatables

///
/// 創(chuàng)建外鍵datatable
///
/// dataset實(shí)例
private dataset builddatatables()
{
dataset ds = new dataset();

datatable table;
datacolumncollection columns;

table = new datatable("sysforeignkeys");
columns = table.columns;

columns.add("fkeyid", typeof(system.int32));
columns.add("fkey", typeof(system.int32));
ds.tables.add(table);

return ds;
}

#endregion
}
}



使用該類(lèi)時(shí)需要在dbms中建一張系統(tǒng)表,并維護(hù)表中的數(shù)據(jù),該表用來(lái)記錄系統(tǒng)中各用戶(hù)表的大概含義,用來(lái)告訴用戶(hù)是什么地方發(fā)生了沖突:

create table systables
(
id int not null identity(1,1) primary key clustered, /*id*/
tablename varchar(255), /*用戶(hù)表名稱(chēng)*/
description varchar(255) /*用戶(hù)表描述*/
)



調(diào)用示例:

public bool test()
{
//數(shù)據(jù)庫(kù)連接字符串
string connectionstring = "";

using (sqlconnection conn = new sqlconnection(connectionstring))
{
conn.open();
using (sqltransaction trans = conn.begintransaction())
{
try
{
string execsqlstring = "delete from test where id = 1";
string errtext = "";

if (!new check().ckeckfkbegindelete(trans, "test", 1, ref errtext))
{
trans.rollback();
return false;
}

sqlhelper.executenonquery(trans, commandtype.text, execsqlstring);
trans.commit();
return true;
}
catch
{
trans.rollback();
throw;
}
}
}
}



代碼中用到ms的sqlhelper類(lèi),可以到http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp下載。目前該類(lèi)僅適用于sql server數(shù)據(jù)庫(kù)


發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 贞丰县| 镇雄县| 汽车| 阆中市| 北川| 遂川县| 西峡县| 蕉岭县| 黄山市| 仁怀市| 绩溪县| 通江县| 原阳县| 东丰县| 富源县| 密山市| 兴宁市| 吉首市| 西充县| 兴业县| 拜城县| 米易县| 丹寨县| 洛阳市| 广德县| 白城市| 皋兰县| 霞浦县| 临泽县| 北碚区| 南安市| 灯塔市| 龙口市| 柳江县| 邳州市| 光泽县| 抚远县| 巴青县| 安陆市| 通城县| 九龙坡区|