views:

334

answers:

2

Before deleting a row from a table, is there any simple way to check that it would violate a referential integrity rule? I'd like to do this from a C# win form application (.Net 3.5) using SQL Server 2005.

A: 

You might do the delete inside a transaction:

try
{
  begin transaction
  delete row
}
catch SQLException
{
  if SQL error indicates referential integrity violation
    throw ReferentialIntegrityViolationException
}
finally
{
  rollback transaction
}

(assuming you never want the delete to take place at this point in your code)

Michael Petrotta
I would think the idea would be to determine if a rule is violated without the performance cost of actually performing the delete. This solution has all the performance problems and none of the benefits ;)
Mystere Man
Why? An FK check is effectively SELECT * FROM ChildTable WHERE FKCOl = ParentKey. To do this up front is an extra round trip. It's arguably easier to handle the error
gbn
...without using a stored proc and encapsulating the SQL call so it's all one round trip.
gbn
@gbn: I'm not arguing that this is an optimal solution, but a FK check is not as you describe. There may be many constraints, and not all may be easy to check with a query. Then, the first time the DBA adds a new constraint (as they're wont to do), your query-based check is broken.
Michael Petrotta
@Michael. Very sorry: my comment was directed as Mystere man. I agree with your solution. Even if a stored proc call was made, an explicit check made, SQL still has to communicate a failure to the client and I'd throw a SQL exception anyway because it implies "processing stopped" too.
gbn
+1  A: 

There are a few potential options that come to mind:

  • Set up cascading deletes in the database so that a delete will always succeed.
  • Check for related records with SELECTs before deleting. This requires that the application have knowledge of the constraints.
  • A good domain model (business classes) should allow the application to be aware of related records.
  • An O/R Mapper, such as NHibernate, can be used to define cascade delete operations.
  • Use SMO (Microsoft.SqlServer.Smo) to inspect the database schema for relations, then check for existing related records. I don't know if that's possible.
Jamie Ide