这个问题可能看起来有点奇怪。但让我解释一下我的真正问题。
在我的系统中,有建筑数据,用户可以自由地向系统添加数据。稍后将审核所有用户数据。有时,用户将建筑物A添加为“Foo A”。有时,他们将其添加为“Foo bar A”。这两个记录都指的是同一个真实世界的对象。
对于管理员,他们需要检查所有输入数据,并用正确的替换所有无效。但是,在用户添加新建筑物之后。他们还在其他表中使用这个新建筑,如“订单”表。
我需要一些SQL脚本(SQL Server 2008或更高版本)来使用新数据更新所有关联数据。之后,我可以安全地从数据库中删除无效数据。
谢谢,
PS.1我有这么多表。我无法为每个表手动编写一些脚本。
PS.2关联表中的列名可能不是“BuildingId”,因此我们不能使用“BuildingId”作为搜索条件来查找关联表。
答案 0 :(得分:2)
假设依赖表'字段名称将始终包含 BuildingID,您可以使用动态SQL来构建更新语句,然后将它们粘贴到新的代码窗口中:
USE DatabaseName
DECLARE @OldBuildingID INT = 123
DECLARE @NewBuildingID INT = 456
select 'UPDATE DatabaseName.dbo.' + columns.TABLE_NAME + ' SET ' + columns.column_name +' = ' + CAST(@NewBuildingID AS VARCHAR(10)) + ' WHERE ' + columns.column_name + ' = ' + CAST(@OldBuildingID AS VARCHAR(10)) + ';' AS SQLDeleteStatement
from information_schema.COLUMNS columns
INNER JOIN sys.objects tables ON columns.TABLE_NAME = tables.name
where columns.COLUMN_NAME like '%BuildingID%'
AND tables.[type] = ( 'U' )
答案 1 :(得分:1)
对于此示例,我尝试删除系统的用户。但是,此用户已从许多其他表中引用。我需要将其他表中的所有引用值更新为新值。
首先,我声明一些变量以保留所有参数。
DECLARE @sql nvarchar (255);
DECLARE @refTableName varchar(255) = 'User'
DECLARE @refColName varchar(255) = 'Id'
DECLARE @refValue uniqueidentifier = '2a8a0f61-fe5c-4dd7-8e6d-00c8340333c4'
-- Deleted User Key
DECLARE @refNewValue uniqueidentifier = '99999999-9999-9999-9999-999999999999'
其次,我通过FOREIGN KEY约束查询所有引用的列/表。
DECLARE RelatedTableCursor CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT
result.TableName,
result.ColumnName
FROM
(
SELECT
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id,fc.parent_column_id) AS ColumnName,
SCHEMA_NAME(o.SCHEMA_ID) ReferenceSchemaName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
) result
WHERE
ReferenceTableName = @refTableName AND ReferenceColumnName = @refColName
接下来,我将所有引用的值更改为新值。
OPEN RelatedTableCursor
WHILE 1 = 1
BEGIN
DECLARE @tableName varchar(255)
DECLARE @columnName varchar(255)
FETCH NEXT FROM RelatedTableCursor into @tableName, @columnName
IF @@fetch_status <> 0
BEGIN
BREAK
END
DECLARE @sql nvarchar (255);
SET @sql =
N'UPDATE [' + @tableName + ']' +
'SET ' +
' [' + @columnName + '] = ''' + CONVERT(NVARCHAR(255), @refNewValue) + '''' +
'WHERE [' + @columnName + '] = ''' + CONVERT(NVARCHAR(255), @refValue) + '''';
-- Prevent some error (Duplicate record) that occurs when replace data in mapping table.
BEGIN TRY
exec sp_executesql @sql;
END TRY
BEGIN CATCH
END CATCH
END
CLOSE RelatedTableCursor
DEALLOCATE RelatedTableCursor
最后,我安全地删除了这些数据,没有关于FOREIGN KEY约束的错误。
SET @sql = 'DELETE FROM [' + @refTableName + '] WHERE ' + @refColName + ' = ''' + CONVERT(NVARCHAR(255), @refValue) + '''';
EXEC sp_executesql @sql;
对于源代码,请转到以下链接。