Sql server 从整个数据库中删除客户记录

Sql server 从整个数据库中删除客户记录,sql-server,tsql,Sql Server,Tsql,场景-客户可能决定不再需要我们数据库中的任何数据,或者我们的集成团队要求删除特定的客户记录,以便插入新的/最新的数据(例如约100万客户)。 我正试图找到一个从数据库中删除客户记录的解决方案,这是为任何给定客户手动运行的 我们有一个存储过程,它似乎可以做到这一点,但是在生产环境中,它可能会导致性能问题—必须有更好的方法来执行此任务 当前,我们扫描所有保存客户数据的表(例如,我们选择所有包含“CustomerID”列的用户表,并保留其余的)。总计约有300张表 一旦is有了这个列表,它就会通过一个

场景-客户可能决定不再需要我们数据库中的任何数据,或者我们的集成团队要求删除特定的客户记录,以便插入新的/最新的数据(例如约100万客户)。

我正试图找到一个从数据库中删除客户记录的解决方案,这是为任何给定客户手动运行的

我们有一个存储过程,它似乎可以做到这一点,但是在生产环境中,它可能会导致性能问题—必须有更好的方法来执行此任务

当前,我们扫描所有保存客户数据的表(例如,我们选择所有包含“CustomerID”列的用户表,并保留其余的)。总计约有300张表

一旦is有了这个列表,它就会通过一个游标(我们可能需要避开这个游标)遍历所有的表,并用一个类似“WHERE CustomerID=@Customer ID”的语句删除记录,所以它需要执行大约300次(每个表一次)

有时它很快,有时它会导致死锁,并导致其他进程执行不良

查看实际执行计划也会导致大量问题,因为它试图显示300个事务

这与存储过程目前所做的差不多

CREATE PROCEDURE [dbo].[RemoveCustomerData]
    @CustomerNo VARCHAR(20) = 'TestDelete'

AS

DECLARE
    @TableName VARCHAR (50),
    @DatabaseName VARCHAR(50),
    @SchemaName VARCHAR(50),
    @ColumnName VARCHAR(50),
    @ObjectName VARCHAR(50),
    @SQL NVARCHAR(MAX),
    @CustomerID INT;

SELECT
    @CustomerID = CustomerID
FROM
    Customers
WHERE
    CustomerNo = @CustomerNo;

DECLARE
    @Tables TABLE (
                    DatabaseName sysname,
                    SchemaName sysname,
                    TableName sysname,
                    ColumnName sysname
                    )
SET
    @SQL = 'SELECT
                ''' + DB_NAME() + ''' AS DatabaseName,
                schemas.name AS SchemaName,
                tables.name AS TableName,
                columns.name AS ColumnName
            FROM
                ' + DB_NAME() + '.sys.tables 
                JOIN ' + DB_NAME() + '.sys.schemas ON schemas.schema_id = tables.schema_id JOIN ' + DB_NAME() + '.sys.columns ON columns.object_id = tables.object_id 
            WHERE
                columns.name IN (''CustomerID'')'

INSERT INTO @Tables
EXEC(@SQL)

--Clear data from tables    
DECLARE
    ClearDownCursor
CURSOR FOR  
SELECT
    *
FROM
    @Tables
OPEN
    ClearDownCursor; 
FETCH NEXT FROM
    ClearDownCursor
INTO
    @DatabaseName,
    @SchemaName,
    @TableName,
    @ColumnName; 

SET @ObjectName =  @DatabaseName + '.' + @SchemaName + '.' + @TableName

--Deletes from table
SET @SQL = 'DELETE FROM ' + @ObjectName + ' WHERE CustomerID = @CustomerID'
EXEC sys.sp_executesql @SQL,  N'@CustomerID INT', 
        @CustomerID = @CustomerID;

FETCH NEXT FROM
    ClearDownCursor
INTO
    @DatabaseName,
    @SchemaName,
    @TableName,
    @ColumnName; 

CLOSE ClearDownCursor;
DEALLOCATE ClearDownCursor;

你不能用一个简单的、甚至不知道数据库模式是什么的盲存储过程来处理GDPR/Right to forget,你真的需要删除所有表中的数据还是个人识别信息?别介意,
CustomerID
对于不同的表可能意味着不同的东西,谁说你可以删除所有这样的记录?财务数据需要保存一定数量的年份,GDPR会考虑到这一点。外键约束不允许您删除任意记录。要添加@IAmDave要求的内容,仅删除PII是不够的-未经同意,不应将其存储在第一位置。即使获得同意,您也需要一种方法在其有效期到期时将其全部删除,这对于所有类型(例如联系人和财务)都不相同。您需要扫描表格这一事实表明,您不知道客户可能位于何处,也不知道哪些表格与其数据相关;这本身就是个问题。正如@PanagiotisKanavos所提到的,被遗忘的权利并不能直接转化为“删除数据”;有时,由于监管或法律义务(例如,上个月之前有效的汽车保险单的驾驶员姓名),您实际上无法满足要求。“遗忘”的形式也使人完全无法辨认。