He mejorado la solución de Alex Aza.
Uso softdelete, por lo que es necesario agregar una columna "eliminar" en la condición "donde". Y más hice una función en TSQL que descubre cuando la tabla representa el objeto heredado en NHibernate, y PK es el FK de la tabla padre.
siga:
declare @RowId int = 4
declare @TableName sysname = 'TABLE'
declare @Command varchar(max)
select @Command = isnull(@Command + ' union all ', '') + 'select ''' + object_name(parent_object_id) +
''' where exists(select * from ' + object_name(parent_object_id) +
CASE
WHEN EXISTS(select object_name(object_id) from sys.columns col where name = 'deleted' and object_id = parent_object_id)
THEN ' where ' + col.name+ ' = ' + cast(@RowId as varchar) +' and deleted = 0 '
when dbo.ParentIdFromTable(object_name(parent_object_id)) <> ''
then ' inner join ' + dbo.ParentIdFromTable(object_name(parent_object_id)) + ' on id = ' + dbo.PrimaryKey(object_name(parent_object_id))
+' where ' + col.name+ ' = ' + cast(@RowId as varchar) +' and deleted = 0 '
else
' where ' + col.name+ ' = ' + cast(@RowId as varchar)
END
+ ')'
from sys.foreign_key_columns fkc
join sys.columns col on
fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
where object_name(referenced_object_id) = @TableName
PRINT @Command
execute (@Command)
depedencies Funciones:
CREATE FUNCTION dbo.ParentIdFromTable(@Table varchar(255))
RETURNS varchar(255)
AS
BEGIN
declare @tableParent varchar(255) = ''
if exists(select pk.TABLE_NAME, pk.COLUMN_NAME, col.name, object_name(referenced_object_id) Referenced, object_name(parent_object_id) as Parent
from sys.columns col
inner join sys.foreign_key_columns fkc on
fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = @table)
begin
while exists(select *
from sys.columns col
inner join sys.foreign_key_columns fkc on
fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1 AND table_name = @table)
begin
-- Descobrir o parent, column
select @tableParent = object_name(referenced_object_id)
from sys.columns col
inner join sys.foreign_key_columns fkc on
fkc.parent_object_id = col.object_id and fkc.parent_column_id = col.column_id
inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE pk on
pk.TABLE_NAME = object_name(object_id) and pk.COLUMN_NAME = col.name
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = @table
--print @tableParent
set @table = @tableParent
end
end
return @tableParent;
END;
GO
CREATE FUNCTION dbo.PrimaryKey(@Table varchar(255))
RETURNS varchar(255)
AS
BEGIN
declare @columnName varchar(255) = ''
-- Descobrir o parent, column
select @columnName = COLUMN_NAME
from INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = @Table
return @columnName
end;
posible duplicado de [Ayuda en el gatillo de SQL Server] (http://stackoverflow.com/questions/6244077/help-on-sql -server-trigger) – gbn
Mi objetivo no es provocar una eliminación en cascada, sino saber de antemano si el registro es eliminable. Si no es eliminable, se notificará al usuario que no se puede eliminar. – Yeonho
Sé que ya ha marcado una respuesta, pero si se trata de un sistema multiusuario, la mejor respuesta puede ser simplemente intentar eliminar y hacer frente a un error; de lo contrario, se pueden realizar todo tipo de condiciones de carrera aquí, salvo envuelve todo en una transacción con alto aislamiento. –