Bỏ tất cả các bảng có tên bắt đầu bằng một chuỗi nhất định


150

Làm cách nào tôi có thể bỏ tất cả các bảng có tên bắt đầu bằng một chuỗi đã cho?

Tôi nghĩ rằng điều này có thể được thực hiện với một số SQL động và các INFORMATION_SCHEMAbảng.

Câu trả lời:


151

Bạn có thể cần sửa đổi truy vấn để bao gồm chủ sở hữu nếu có nhiều hơn một cơ sở dữ liệu.

DECLARE @cmd varchar(4000)
DECLARE cmds CURSOR FOR
SELECT 'drop table [' + Table_Name + ']'
FROM INFORMATION_SCHEMA.TABLES
WHERE Table_Name LIKE 'prefix%'

OPEN cmds
WHILE 1 = 1
BEGIN
    FETCH cmds INTO @cmd
    IF @@fetch_status != 0 BREAK
    EXEC(@cmd)
END
CLOSE cmds;
DEALLOCATE cmds

Điều này sạch hơn so với sử dụng cách tiếp cận hai bước tạo tập lệnh cộng với chạy. Nhưng một lợi thế của việc tạo tập lệnh là nó cho bạn cơ hội để xem lại toàn bộ những gì sẽ được chạy trước khi nó thực sự chạy.

Tôi biết rằng nếu tôi định làm điều này với cơ sở dữ liệu sản xuất, tôi sẽ cẩn thận nhất có thể.

Sửa mã mẫu cố định.


5
Bạn có thể phải chạy tập lệnh này nhiều lần vì các ràng buộc khóa ngoài giữa bảng chính và bảng chi tiết.
Alexander Prokofyev

7
Trong SQL Server 2005 tôi đã phải thay đổi hai dòng cuối cùng thành close cmds; deallocate cmds.
Hamish Grubijan

Cảnh báo : Giải pháp này cũng có thể xóa các bảng được tạo bởi SQL Server! Giải pháp của tôi dưới đây tránh điều này và xóa các bảng theo thứ tự phụ thuộc khóa ngoài.
Tony O'Hagan

Điều này đã không làm việc cho tôi. Câu trả lời cho câu hỏi này đã có hiệu quả: stackoverflow.com/questions/5116296/ từ
Ayushmati

115
SELECT 'DROP TABLE "' + TABLE_NAME + '"' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

Điều này sẽ tạo ra một kịch bản.

Thêm mệnh đề để kiểm tra sự tồn tại của bảng trước khi xóa:

SELECT 'IF OBJECT_ID(''' +TABLE_NAME + ''') IS NOT NULL BEGIN DROP TABLE [' + TABLE_NAME + '] END;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

10
Tôi có thể thêm để xóa dấu ngoặc khi thay thế "tiền tố" bằng tiền tố đích của bạn.
Levitikon

10
MYSQL: CHỌN concat ('DROP TABLE', TABLE_NAME, ";") dưới dạng dữ liệu TỪ THÔNG TIN_SCHema.TABLES WHERE TABLE_NAME THÍCH '[tiền tố]%' --- cho những người như tôi đã tìm thấy chủ đề này
Andre

1
Kết quả cũng chứa các lượt xem
Ondra

1
Đừng quên thoát _ nếu đó là một phần của tiền tố của bạn, vd. WHERE TABLE_NAME LIKE 'em\_%' ESCAPE '\';
EM0

3
Điều này tạo ra một tập lệnh, nhưng làm thế nào để thực thi tập lệnh?
daOnlyBG

16

Điều này sẽ giúp bạn có được các bảng theo thứ tự khóa ngoài và tránh bỏ một số bảng được tạo bởi SQL Server. Các t.Ordinalgiá trị sẽ cắt các bảng thành các lớp phụ thuộc.

WITH TablesCTE(SchemaName, TableName, TableID, Ordinal) AS
(
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        0 AS Ordinal
    FROM sys.objects AS so
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'

    UNION ALL
    SELECT OBJECT_SCHEMA_NAME(so.object_id) AS SchemaName,
        OBJECT_NAME(so.object_id) AS TableName,
        so.object_id AS TableID,
        tt.Ordinal + 1 AS Ordinal
    FROM sys.objects AS so
        INNER JOIN sys.foreign_keys AS f
            ON f.parent_object_id = so.object_id
                AND f.parent_object_id != f.referenced_object_id
        INNER JOIN TablesCTE AS tt
            ON f.referenced_object_id = tt.TableID
    WHERE so.type = 'U'
        AND so.is_ms_Shipped = 0
        AND OBJECT_NAME(so.object_id)
        LIKE 'MyPrefix%'
)
SELECT DISTINCT t.Ordinal, t.SchemaName, t.TableName, t.TableID
FROM TablesCTE AS t
    INNER JOIN
    (
        SELECT
            itt.SchemaName AS SchemaName,
            itt.TableName AS TableName,
            itt.TableID AS TableID,
            Max(itt.Ordinal) AS Ordinal
        FROM TablesCTE AS itt
        GROUP BY itt.SchemaName, itt.TableName, itt.TableID
    ) AS tt
        ON t.TableID = tt.TableID
            AND t.Ordinal = tt.Ordinal
ORDER BY t.Ordinal DESC, t.TableName ASC


3
Khắc phục nhanh: TableName xuất hiện một vài lần trong các mệnh đề WHERE và nên được thay thế bằng OBJECT_NAME (so.object_id). Kịch bản hay!
witttness

6

Trên Oracle XE, công việc này:

SELECT 'DROP TABLE "' || TABLE_NAME || '";'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

Hoặc nếu bạn muốn loại bỏ các ràng buộc và giải phóng không gian , hãy sử dụng điều này:

SELECT 'DROP TABLE "' || TABLE_NAME || '" cascade constraints PURGE;'
FROM USER_TABLES
WHERE TABLE_NAME LIKE 'YOURTABLEPREFIX%'

Điều này sẽ tạo ra một loạt các DROP TABLE cascade constraints PURGEbáo cáo ...

Để VIEWSsử dụng này:

SELECT 'DROP VIEW "' || VIEW_NAME || '";'
FROM USER_VIEWS
WHERE VIEW_NAME LIKE 'YOURVIEWPREFIX%'

Làm việc hoàn hảo. Có 61.037 bảng trống để xóa khỏi db được sử dụng cho QA. Tôi đã sử dụng ví dụ ràng buộc tầng. Tạo đầu ra sau đó sao chép tất cả vào một tập lệnh và chạy nó. Mất mãi mãi nhưng nó làm việc như một cơ duyên! Cảm ơn!
tehbeardedone

5

Tôi đã thấy bài đăng này khi tôi đang tìm kiếm câu lệnh mysql để loại bỏ tất cả các bảng WordPress dựa trên @Xenph Yan, đây là những gì tôi đã làm cuối cùng:

SELECT CONCAT(  'DROP TABLE `', TABLE_NAME,  '`;' ) AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE  'wp_%'

điều này sẽ cung cấp cho bạn bộ truy vấn thả cho tất cả các bảng bắt đầu bằng wp_


5

Đây là giải pháp của tôi:

SELECT CONCAT('DROP TABLE `', TABLE_NAME,'`;') 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'TABLE_PREFIX_GOES_HERE%';

Và tất nhiên bạn cần thay thế TABLE_PREFIX_GOES_HEREbằng tiền tố của bạn.


5
EXEC sp_MSforeachtable 'if PARSENAME("?",1) like ''%CertainString%'' DROP TABLE ?'

Biên tập:

sp_MSforeachtable không có giấy tờ do đó không phù hợp để sản xuất vì hành vi của nó có thể thay đổi tùy thuộc vào phiên bản MS_Query.


Tuyệt vời một lót! Điều này nên được bình chọn lên hàng đầu.
dùng3413723

4
CREATE PROCEDURE usp_GenerateDROP
    @Pattern AS varchar(255)
    ,@PrintQuery AS bit
    ,@ExecQuery AS bit
AS
BEGIN
    DECLARE @sql AS varchar(max)

    SELECT @sql = COALESCE(@sql, '') + 'DROP TABLE [' + TABLE_NAME + ']' + CHAR(13) + CHAR(10)
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME LIKE @Pattern

    IF @PrintQuery = 1 PRINT @sql
    IF @ExecQuery = 1 EXEC (@sql)
END

2

Câu trả lời của Xenph Yan sạch hơn tôi rất nhiều nhưng đây là của tôi.

DECLARE @startStr AS Varchar (20)
SET @startStr = 'tableName'

DECLARE @startStrLen AS int
SELECT @startStrLen = LEN(@startStr)

SELECT 'DROP TABLE ' + name FROM sysobjects
WHERE type = 'U' AND LEFT(name, @startStrLen) = @startStr

Chỉ cần thay đổi tableNamecác ký tự mà bạn muốn tìm kiếm.


1

Điều này làm việc cho tôi.

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += '
DROP TABLE ' 
    + QUOTENAME(s.name)
    + '.' + QUOTENAME(t.name) + ';'
    FROM sys.tables AS t
    INNER JOIN sys.schemas AS s
    ON t.[schema_id] = s.[schema_id] 
    WHERE t.name LIKE 'something%';

PRINT @sql;
-- EXEC sp_executesql @sql;

0
select 'DROP TABLE ' + name from sysobjects
where type = 'U' and sysobjects.name like '%test%'

- Kiểm tra là tên bảng


Điều này không thực sự thực thi bất cứ điều gì, chỉ cần trả về một loạt các lệnh.
Rabbi tàng hình

0
SELECT 'if object_id(''' + TABLE_NAME + ''') is not null begin drop table "' + TABLE_NAME + '" end;' 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE '[prefix]%'

0

Tôi đã phải làm một dẫn xuất nhỏ về câu trả lời của Xenph Yan Tôi nghi ngờ vì tôi có các bảng không có trong lược đồ mặc định.

SELECT 'DROP TABLE Databasename.schema.' + TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_NAME LIKE 'strmatch%'

0

Trong trường hợp các bảng tạm thời, bạn có thể muốn thử

SELECT 'DROP TABLE "' + t.name + '"' 
FROM tempdb.sys.tables t
WHERE t.name LIKE '[prefix]%'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.