AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 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

Script para excluir registros em várias tabelas

  • 772

Gostaria de excluir um registro específico de duas ou mais tabelas vinculadas entre si.

Por exemplo: Tenho duas mesas, Alunos e vencedores. Gostaria de excluir os nomes Roy e Peter de ambas as mesas de uma só vez.

mesa: alunos

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

mesa: vencedores

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

Tenho mais de 100 tabelas com 50 registros específicos para serem deletados de todas as tabelas.

sql-server sql-server-2008
  • 4 4 respostas
  • 26748 Views

4 respostas

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

    Você tem que conseguir isso usando Dynamic SQL Query

    1- Primeiro você tem que listar todas as Tabelas com os Bancos de Dados Correspondentes em uma StudentsTabela WinnersTemp

    Seu script deve se parecer

    --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
    

    Isso resultará em uma consulta como a seguinte ( se esses bancos de dados contiverem uma tabelaStudentsWinners )

    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')  ;     
    

    Eu não agora, se é isso que você estava pedindo em sua pergunta abaixo (sua pergunta não foi específica como esta, então minha resposta foi fornecer a lógica sql dinâmica em geral)

    • Truncar com cláusula where
    • 2
  2. George K
    2017-04-18T22:56:04+08:002017-04-18T22:56:04+08:00

    Você terá que listar explicitamente as tabelas das quais precisa excluir de qualquer maneira.

    Um dos cenários seria criar uma tabela com a lista de tabelas que você deseja excluir e percorrer cada uma delas aplicando a deleteinstrução apropriada com base nos id'salunos com nomes específicos.

    Para percorrer todas as tabelas do banco de dados, você pode usar algo assim:

    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;
    

    E não esqueça de testar deleteno ambiente de teste.

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

    Acho que a abordagem correta é primeiro excluir o registro da tabela do aluno sem o sql dinâmico e armazenar o ID excluído na tabela temporária.

    assim,

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

    No exemplo acima, não preciso usar "where name in()" todas as vezes. Eu uso uma vez e guardo na tabela temporária.

    Por exemplo, estou usando o 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

    De SQL DELETE

    A maioria dos sistemas de gerenciamento de banco de dados permite que você crie uma restrição de chave estrangeira para que, se você excluir uma linha em uma tabela, as linhas correspondentes à tabela relacionada também sejam removidas automaticamente. Isso garante a integridade dos dados.

    E

    Respondido em SO . (Deve ser adaptado à sua situação)

    Você não pode simplesmente separá-los por um ponto e vírgula?

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

    OU

    Basta usar INNER JOIN como abaixo

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

    EDIT devido ao comentário do @NIC (e DV?):

    Primeira opção: table_constraint (Transact-SQL)

    NA EXCLUSÃO { SEM AÇÃO | CASCATA | DEFINIR NULO | SET DEFAULT } Especifica qual ação acontece com as linhas da tabela que é alterada, se essas linhas tiverem um relacionamento referencial e a linha referenciada for excluída da tabela pai. O padrão é SEM AÇÃO.

    ...

    CASCADE As linhas correspondentes são excluídas da tabela de referência se essa linha for excluída da tabela pai.

    ...

    e um exemplo em SO

    Segunda opçao:

    preparar mesas

    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)
    

    Excluindo linhas

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

    Testado no SQL Server 13.0.1722.0 nota: DROP TABLE IF EXIST pode não funcionar em versões mais antigas

    insira a descrição da imagem aqui

    • -1

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve