我正在创建一个asp.net项目,我正在尝试删除数据库中的一行,但该表有约束。我正在使用此方法删除它。如何重写它以便禁用所有约束或某些东西以便我可以从表中正确删除一行。
public bool DeleteMovie(int MovieID)
{
string sql = "DELETE FROM DBS2_MOVIE WHERE MOVIE_ID = :AccountID ";
try
{
this.Connect();
OracleCommand cmd = new OracleCommand(sql, this.connection);
cmd.Parameters.Add(new OracleParameter("AccountID", MovieID));
OracleDataReader DataRead = cmd.ExecuteReader();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
finally
{
this.connection.Close();
}
return true;
}
答案 0 :(得分:1)
最好的方法是在C#代码中使用存储的proceed而不是sql语句。您收到错误,因为引用的记录仍然存在于引用的表中,并且使用cmd.ExecuteReader();
而不是cmd.ExecuteNonQuery();
。因此,您需要从存在表DBS2_MOVIE约束的所有表中删除DBS2_MOVIE WHERE MOVIE_ID = :AccountID
的记录。
以下代码可以帮助您:
CREATE OR REPLACE PROCEDURE Delete_DBS2_MOVIE(p_MOVIE_ID IN DBS2_MOVIE.MOVIE_ID%TYPE) IS BEGIN --First delete p_MOVIE_ID from all the table where there is a constraint on DBS2_MOVIE --i.e. all the constraints you are getting error for DELETE FROM XXX WHERE MOVIE_ID = p_MOVIE_ID DELETE FROM DBS2_MOVIE WHERE MOVIE_ID = p_MOVIE_ID; END;
将您的C#代码修改为:
public bool DeleteMovie(int MovieID)
{
string sql = "Delete_DBS2_MOVIE";
try
{
this.Connect();
OracleCommand cmd = new OracleCommand(sql, this.connection);
cmd.Parameters.Add(new OracleParameter("p_MOVIE_ID", MovieID));
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.ExecuteNonQuery();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw;
}
finally
{
this.connection.Close();
}
return true;
}
答案 1 :(得分:1)
1)通过禁用约束删除不是最佳做法。您无法保持数据完整性。数据完整性是数据库的首要考虑因素,因为没有它,你什么都没有。
正确的方法是在尝试删除父记录之前从子表中删除。如果通过禁用约束可以删除它,则使用此存储过程
CREATE proc [dbo].[DeleteMovie]
@AccountID int
as
begin
-- disable all constraints
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
DELETE FROM DBS2_MOVIE WHERE MOVIE_ID = @AccountID
-- enable all constraints
exec sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
end
或将sp-msforeachtable
附加到您的查询中。
StringBuilder sql=new StringBuilder();
sql.Append("EXEC sp_msforeachtable \"ALTER TABLE ? NOCHECK CONSTRAINT all\"");
sql.Append("DELETE FROM DBS2_MOVIE WHERE MOVIE_ID = :AccountID");
sql.Append("exec sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"");
我们只需要添加这些行
- 禁用所有约束
EXEC sp_msforeachtable“ALTER TABLE?NOCHECK CONSTRAINT all”- 启用所有约束
执行sp_msforeachtable @ command1 =“print'?'”,@ command2 =“ALTER TABLE?WITH CHECK CHECK CONSTRAINT all”
我建议你使用存储过程来执行查询,因为它会创建抽象。即使我们使用参数化语句,使用存储过程来避免SQL注入问题也更安全。 Owasp表明了这一点。