AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 171254
Accepted
l.lijith
l.lijith
Asked: 2017-04-18 22:05:04 +0800 CST2017-04-18 22:05:04 +0800 CST 2017-04-18 22:05:04 +0800 CST

删除多个表中记录的脚本

  • 772

我想从两个或多个相互链接的表中删除特定记录。

例如:我有两张桌子,Students 和 Winners 我想一次性从两张桌子上删除 Roy 和 Peter 的名字。

表:学生

> ID     name      class
> 1      Roy         2
> 2      James       3
> 3      Carl        4
> 4      Peter       4
> 5      Alice       5

表:获奖者

St_ID          achievement
1              1
2              1
3              3
4              5
5              5

我有 100 多个表,其中 50 条特定记录要从所有表中删除。

sql-server sql-server-2008
  • 4 4 个回答
  • 26748 Views

4 个回答

  • Voted
  1. Best Answer
    Hadi
    2017-04-19T20:48:28+08:002017-04-19T20:48:28+08:00

    您必须使用动态 SQL 查询来实现这一点

    1-首先,您必须在临时表中列出所有具有相应数据库的表 2-为包含Students和WinnersdataTable的数据库构建查询

    你的脚本应该看起来像

    --Get all Databases With corresponding Database
    
    declare @SQL nvarchar(max)
    DECLARE @strQuery AS NVARCHAR(MAX)
    
    SET @strQuery = ''
    
    CREATE TABLE #TblTemp (DatabaseName Varchar(255), Tablename Varchar(255))
    
    
    
    set @SQL = (select 'union all 
    select '''+D.name+''' as DatabaseName,
           T.name collate database_default as TableName
    from '+quotename(D.name)+'.sys.tables as T
    '
    from sys.databases as D
    for xml path(''), type).value('substring((./text())[1], 13)', 'nvarchar(max)')
    
    --print @SQL
    INSERT INTO #TblTemp
    exec (@SQL)
    
    -- Building Queries
    
    SELECT @strQuery = @strQuery + 'Delete T1 from [' + name  + '].dbo.Students As T2
                            Inner join  [' + name  + '].dbo.Winners as T1 
                            On T1.[st_ID] = T2.[ID] 
                            Where    T1.[name] = IN(''Roy'',''Peter'')  ;
    
    DELETE FROM [' + name  + '].dbo.Students WHERE [name] = IN(''Roy'',''Peter'') ;
    
    '
    
     from sys.databases
     WHERE EXISTS (SELECT 1 FROM #TblTemp WHERE #TblTemp.DatabaseName = name AND #TblTemp.TableName = 'Students') AND
     EXISTS (SELECT 1 FROM #TblTemp WHERE #TblTemp.DatabaseName = name AND #TblTemp.TableName = 'Winners')
    
    --VIEW QUERIES (you can copy result and execute it manually)
    SELECT @strQuery
    
    
    
    --EXECUTE QUERIES
    EXEC(@strQuery)
    
    --DROP Temp Table 
    DROP TABLE #TblTemp
    

    这将导致如下查询(如果这些数据库包含Students和Winners表)

    Delete T1 from [master].dbo.Students As T2   Inner join  [master].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     
    DELETE FROM [master].dbo.Students WHERE [name] = IN('Roy','Peter') ;     
    Delete T1 from [tempdb].dbo.Students As T2   Inner join  [tempdb].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     
    DELETE FROM [tempdb].dbo.Students WHERE [name] = IN('Roy','Peter') ;     
    Delete T1 from [model].dbo.Students As T2   Inner join  [model].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     
    DELETE FROM [model].dbo.Students WHERE [name] = IN('Roy','Peter') ;     
    Delete T1 from [msdb].dbo.Students As T2   Inner join  [msdb].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     
    DELETE FROM [msdb].dbo.Students WHERE [name] = IN('Roy','Peter') ;     
    Delete T1 from [AdventureWorks2008R2].dbo.Students As T2   Inner join  [AdventureWorks2008R2].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     DELETE FROM [AdventureWorks2008R2].dbo.Students WHERE [name] = IN('Roy','Peter') ;     Delete T1 from [DbMail].dbo.Students As T2   Inner join  [DbMail].dbo.Winners as T1    On T1.[st_ID] = T2.[ID]    Where    T1.[name] = IN('Roy','Peter')  ;     
    

    如果这是您在下面的问题中所要求的,我现在不知道(您的问题不像这个问题那样具体,所以我的回答是提供一般的动态 sql 逻辑)

    • 用 where 子句截断
    • 2
  2. George K
    2017-04-18T22:56:04+08:002017-04-18T22:56:04+08:00

    您将不得不明确列出您需要从中删除的表。

    其中一种情况是创建一个表,其中包含要从中删除的表列表,并根据具有特定姓名的学生应用适当delete的语句遍历每个表。id's

    要遍历数据库中的所有表,您可以使用如下内容:

    DECLARE c_tables CURSOR
    FOR SELECT table_name
        FROM INFORMATION_SCHEMA.TABLES;
    
    DECLARE
      @table_name VARCHAR(100);
    
    OPEN c_tables;
    
    FETCH NEXT FROM c_tables INTO
      @table_name;
    
    WHILE @@FETCH_STATUS=0
    BEGIN
    --<your command here>
    FETCH NEXT FROM c_tables INTO
      @table_name;
    END;
    
    CLOSE c_tables;
    
    DEALLOCATE c_tables;
    

    并且不要忘记delete在测试环境中进行测试。

    • 0
  3. KumarHarsh
    2017-05-26T04:04:17+08:002017-05-26T04:04:17+08:00

    我认为正确的方法是首先从没有动态 sql 的学生表中删除记录并将删除的 ID 存储在临时表中。

    像这样,

    DECLARE @DeletedSTID table(id int not null)
    
    delete from Students
    output deleted.id into @DeletedSTID
    where name in('Peter','Roy')
    
    select * from @DeletedSTID
    

    在上面的示例中,我不必每次都使用“where name in()”。我使用它一次并将其存储在临时表中。

    例如我正在使用 Adventure DB,

    USE AdventureWorks2012
    GO
    
    CREATE TABLE #DeletedSTID (id INT NOT NULL)
    
    CREATE TABLE #temp (tablename VARCHAR(100))
    
    DECLARE @Sql VARCHAR(max) = ''
    
    BEGIN TRY
        BEGIN TRANSACTION
    
        DELETE
        FROM HumanResources.EmployeeDepartmentHistory
        OUTPUT deleted.BusinessEntityID
        INTO #DeletedSTID
        WHERE BusinessEntityID IN (
                1
                ,2
                )
    
        INSERT INTO #temp
        SELECT TABLE_NAME
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE COLUMN_NAME = 'BusinessEntityID'
            AND TABLE_NAME NOT LIKE 'v%'
    
        SELECT *
        FROM #DeletedSTID
    
        SELECT *
        FROM #temp
    
        SELECT @Sql = @Sql + ' delete from ' + tablename + ' a where exists 
    (select id from #DeletedSTID b where b.id=a.BusinessEntityID)  '
        FROM #temp
    
        PRINT @Sql
    
        EXEC (@Sql)
    
        ROLLBACK
            --COMMIT
    END TRY
    
    BEGIN CATCH
        IF @@TRANCOUNT > 0
            ROLLBACK
    
        SELECT ERROR_NUMBER() AS ErrorNumber
            ,ERROR_SEVERITY() AS ErrorSeverity
            ,ERROR_STATE() AS ErrorState
            ,ERROR_PROCEDURE() AS ErrorProcedure
            ,ERROR_LINE() AS ErrorLine
            ,ERROR_MESSAGE() AS ErrorMessage;
    END CATCH
    
    DROP TABLE #temp
    
    DROP TABLE #DeletedSTID
    
    • 0
  4. HEDMON
    2017-04-18T23:03:29+08:002017-04-18T23:03:29+08:00

    从SQL 删除

    大多数数据库管理系统允许您创建外键约束,以便如果您删除表中的一行,相关表的相应行也会自动删除。这确保了数据的完整性。

    和

    在 SO 中回答。(必须适应你的情况)

    你不能用分号分隔它们吗?

    Delete from messages where messageid = '1';
    Delete from usersmessages where messageid = '1'
    

    或者

    只需使用 INNER JOIN 如下

    DELETE messages , usersmessages  FROM messages  INNER JOIN usersmessages  
    WHERE messages.messageid= usersmessages.messageid and messages.messageid = '1'
    

    编辑由于@NIC的评论(和DV?):

    第一个选项: table_constraint (Transact-SQL)

    删除时 { 无操作 | 级联 | 设置空 | SET DEFAULT } 指定表中被更改的行发生的操作,如果这些行具有引用关系并且引用的行从父表中删除。默认为无操作。

    ...

    CASCADE 如果从父表中删除该行,则从引用表中删除相应行。

    ...

    和SO 中的一个例子

    第二种选择:

    准备桌子

    DROP TABLE IF EXISTS dbo.Student, dbo.Winner
    
    CREATE TABLE dbo.Student 
    (
        ID          INT         NOT NULL,
        name        VARCHAR(30) NOT NULL,
        class       VARCHAR(30) NOT NULL
    );
    CREATE TABLE dbo.Winner
    (
        stID        INT         NOT NULL,
        achievement INT         NOT NULL
    );
    GO
    
    INSERT INTO dbo.Student(ID, name, class)
    VALUES
        (1, 'Roy', '2'),
        (2, 'James', '2'),
        (3, 'Carl', '2'),
        (4, 'Peter', '2'),
        (5, 'Alice', '2')
    
    INSERT INTO dbo.Winner(stID, achievement)
    VALUES
        (1, 1),
        (2, 1),
        (3, 3),
        (4, 5),
        (5, 5)
    

    删除行

    DELETE FROM Student WHERE ID = 1;
    DELETE FROM Winner WHERE stID = 1
    

    在 SQL Server 13.0.1722.0 中测试 注意:DROP TABLE IF EXIST 可能在旧版本中不起作用

    在此处输入图像描述

    • -1

相关问题

  • 死锁的主要原因是什么,可以预防吗?

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

  • 如何确定是否需要或需要索引

  • 从 SQL Server 2008 降级到 2005

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve