loop through all tables and delete records

久未见 提交于 2019-12-02 03:23:59

问题


I'm new to MsSql and I'm not sure if this can be done but I figured I'd ask before I want on my way with the current process..

I need to create a script that loops through all tables in a database and deletes the rows where CorporationId = "xxx". There are a few tables that do not have this column, but of my ~50 tables, only 1 or two do not.

I can individually delete the records in the table with this:

USE MyDatabase

DECLARE @CorporationId UniqueIdentifier
DECLARE @TokenId UniqueIdentifier
DECLARE @CompanyCode nChar(3)

SET @CorporationId = '52D3AEFE-8EBD-4669-8096-4596FE83BB36'

print 'Starting Web.GasOrder'

DELETE FROM Web.GasOrder
WHERE       CorporationId = @CorporationId

print 'Starting Web.GasOrderNumber'

DELETE FROM Web.GasOrderNumber
WHERE       CorporationId = @CorporationId

etc..

But this is getting tedious creating one for each table.

Of course, some of the tables have relationships on them.

Is there an easy way to do this or do I need to do it manually for each table?

UPDATE

Most of the options that I have tried run into problems with relationships and give me an error.


回答1:


Here's another one... could easily be changed to a stored procedure...

Declare @corpID Nvarchar(256)
Set     @corpID = 'xxx'

If      Object_ID('tempdb..#tables') Is Not Null Drop Table #tables
Create  Table #tables (tID Int, SchemaName Nvarchar(256), TableName Nvarchar(256))

Insert  #tables
Select  Row_Number() Over (Order By s.name, so.name), s.name, so.name
From    sysobjects so
Join    sys.schemas s
        On  so.uid = s.schema_id
Join    syscolumns sc
        On  so.id = sc.id
Where   so.xtype = 'u'
And     sc.name = 'CorporationId'

Declare @SQL Nvarchar(Max),
        @schema Nvarchar(256),
        @table Nvarchar(256),
        @iter Int = 1

While   Exists (Select  1
                From    #tables)
Begin

        Select  @schema = SchemaName,
                @table = TableName
        From    #tables
        Where   tID = @iter

        If      Exists (Select  1
                        From    sysobjects o
                        Join    sys.schemas s1
                                On  o.uid = s1.schema_id
                        Join    sysforeignkeys fk
                                On  o.id = fk.rkeyid
                        Join    sysobjects o2
                                On  fk.fkeyid = o2.id
                        Join    sys.schemas s2
                                On  o2.uid = s2.schema_id
                        Join    #tables t
                                On  o2.name = t.TableName Collate Database_Default
                                And s2.name = t.SchemaName Collate Database_Default
                        Where   o.name = @table
                        And     s1.name = @schema)
        Begin
                Update  t
                Set     tID = (Select Max(tID) From #tables) + 1
                From    #tables t
                Where   tableName = @table
                And     schemaName = @schema

                Set     @iter = @iter + 1
        End
        Else
        Begin
                Set     @Sql = 'Delete t
                                From    [' + @schema + '].[' + @table + '] t
                                Where   CorporationId = ''' + @corpID + ''''

                Exec    sp_executeSQL @SQL;

                Delete  t
                From    #tables t
                Where   tableName = @table
                And     schemaName = @schema

                Set     @iter = @iter + 1

        End
End



回答2:


sp_MSForEachTable is an undocumented stored procedure which will run a command for each table in the database:

USE MyDatabase

DECLARE @CorporationId VARCHAR(50)
SET @CorporationId = '52D3AEFE-8EBD-4669-8096-4596FE83BB36'

DECLARE @Sql VARCHAR(MAX)
SET @Sql = '
IF COL_LENGTH(''?'',''CorporationId'') IS NOT NULL
BEGIN
    DELETE FROM Web.?
    WHERE CorporationId = ''' + @CorporationId + '''
END
'

EXEC sp_MSForEachTable @Sql



回答3:


You could run a query like this:

SELECT 'DELETE FROM [' + s.name + '].[' + t.name + '] WHERE CorporationId = ''52D3AEFE-8EBD-4669-8096-4596FE83BB36'''
FROM sys.columns c
    inner join sys.tables t
        ON t.object_id= c.object_id
    inner join sys.schemas s
        ON s.schema_id = t.schema_id
where c.name = 'CorporationId'

and then either copy and paste the results into a new query window and execute the new query or iterate over the results with a cursor and execute each result with the exec statement.




回答4:


Here is a Sql Fiddle that proves the below query

You can get the tables from this query:

SELECT Name, IsChecked = 0
INTO #Tables
FROM sys.Tables
WHERE EXISTS
(
  SELECT * FROM sys.columns 
  WHERE object_id = OBJECT_ID(sys.Tables.Name) AND sys.columns.Name = 'blah'
) 

Then, you can create a dynamic query and execute it for the tables that you found

WHILE(SELECT COUNT(*) FROM #Tables WHERE IsChecked = 0) > 0
BEGIN
    SELECT TOP 1 @TableName = Name FROM #Tables WHERE IsChecked = 0
    SET     @DeleteQuery = 'DELETE FROM ' + @TableName  + ' WHERE CorporationID = ''' + @CorporationId + ''''
    EXECUTE sp_executeSQL @DeleteQuery;
    UPDATE #Tables SET IsChecked = 1 WHERE Name = @TableName 
END


来源:https://stackoverflow.com/questions/14716025/loop-through-all-tables-and-delete-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!