3

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.

Zoman
  • 2,047
  • 4
  • 28
  • 44
  • I'm not aware of any, but if any such techniques do exist, I imagine the specific technology you're using to access the database would be a pretty fundamental piece of information. – Greg D Jun 06 '09 at 18:23

2 Answers2

1

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
  • 59,888
  • 27
  • 145
  • 179
  • 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 ;) – Erik Funkenbusch Jun 06 '09 at 18:30
  • 1
    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 Jun 06 '09 at 18:33
  • ...without using a stored proc and encapsulating the SQL call so it's all one round trip. – gbn Jun 06 '09 at 18:34
  • @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 Jun 06 '09 at 18:48
  • @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 Jun 07 '09 at 08:02
1

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
  • 48,427
  • 16
  • 81
  • 117