【问题标题】:Drop MySQL databases matching some wildcard?删除与某些通配符匹配的 MySQL 数据库?
【发布时间】:2009-01-19 06:50:12
【问题描述】:

我在需要删除大量数据库的服务器上运行 mySQL(在对服务器进行了一些测试之后)。我需要删除的所有数据库都具有相同的前缀“Whatever_”。

前缀后的名称是随机的。所以你有你的whatever_something,whatever_232,whatever_blabla,....,whatever_imthelast。

我将多次从事这项工作,所以我想知道最好的方法是什么?

编辑: 我可以使用任何类型的语言或插入 mysql ......所以我们可以通过某些方式做到这一点。现在,我要求生成数据库的人给我一个 .txt,每个名称都在一行中...所以我编写了一个快速 php,它将获取一个文件并删除其中的所有数据库,稍后我会尝试% 答案(如果它有效,它肯定会采用正确的答案,这是更简单的方法)。无论如何,我想以更简单的方式做到这一点,因为我将无法支持此代码(其他人会,你知道...)

编辑 2: 使用通配符不起作用:#1008 - Can't drop database 'whatever_%';数据库不存在

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    基本思想是在您的数据库中运行“显示表”,并使用其中的结果来选择 你想要的表。我不认为 MySQL 让你对“显示表”的结果集做任何事情, 但我可能错了。

    这是一个使用 shell 的快速而简单的解决方案:

    mysql -u your_user -D your_database_name -e "show tables" -s | 
      egrep "^Whatever_" | 
      xargs -I "@@" echo mysql -u your_user -D your_database_name -e "DROP TABLE @@"
    

    这将打印出所有 shell 命令以删除以“Whatever_”开头的表。如果您希望它实际执行这些命令,请删除“echo”一词。

    编辑:我忘了解释上面的内容!我不知道你对 shell 脚本有多熟悉,但这里是:

    mysql -u your_user -D your_database_name -e "show tables" -s
    

    打印出所有表的列表,标题为“Tables_in_your_database_name”。输出通过下一个命令通过管道(| 符号表示“管道”,如传递):

    egrep "^Whatever_"
    

    搜索以单词“Whatever_”开头的任何行(^ 符号表示“存在”)并仅打印这些行。最后,我们通过命令通过管道传输“Whatever_*”表列表:

    xargs -I "@@" echo mysql -u your_user -D your_database_name -e "DROP TABLE @@"
    

    获取表名列表中的每一行,并插入它而不是命令中的“@@”

    echo mysql -u your_user -D your_database_name -e "DROP TABLE @@"
    

    因此,如果您有一堆名为“Whatever_1”、“Whatever_2”、“Whatever_3”的表,生成的命令将是:

    echo mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_1"
    echo mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_2"
    echo mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_3"
    

    这将输出以下内容:

    mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_1"
    mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_2"
    mysql -u your_user -D your_database_name -e "DROP TABLE Whatever_3"
    

    我希望这是足够的细节,而且我不只是用太多的信息打败任何人。祝你好运,使用“DROP TABLE”命令时要小心!

    【讨论】:

    • 对我来说它不会在-e 之后输出引号(")。它使用您的确切 bash 脚本输出如下行:mysql -u root -D joomla_test -e DROP TABLE bak_xlr1q_weblinks。我正在使用 Bash 4.1.5(1)-release。
    • @Codemonkey 要使引号出现,您可以对其进行转义。将"DROP TABLE @@" 替换为\"DROP TABLE @@\"
    • 很好的答案!您可能会考虑使用printf 而不是echo 以避免在引号等方面出现不一致的行为,但这相当小:)
    【解决方案2】:

    scraimer的回答原则是正确的,但是由于问题是关于删除数据库而不是数据库中的表,因此正确的命令应该是:

    mysql -u your_username -p'your password' -e 'show databases' 
    | grep Whatever_* 
    | xargs -I "@@" mysql -u your_username -p'your password' -e "DROP database \`@@\`"
    

    有关命令的解释,请查看 scraimer 的解释。

    最后一点... \`@@\` 我们在 bacticks(`) 中引用生成的数据库名称,以防我们的数据库名称包含特殊字符,例如 `-`

    干杯

    【讨论】:

    • 对我来说最好在 grep 部分使用正则表达式:| grep -e ".*_backup" 选择所有以“_backup”结尾的数据库
    • 对于将其复制粘贴到终端的任何人 - 请在命令前加上前导空格。这具有不将命令(使用纯文本密码!)存储在命令历史记录中的效果。
    【解决方案3】:

    我们可以使用存储过程来做到这一点。下面是一个:

    drop procedure if exists droplike;
    delimiter //
    create procedure droplike(pattern varchar(20))
    begin
      set group_concat_max_len = 65535;
      select @drop:= concat( 'drop table ', group_concat(table_name) , ';' ) from information_schema.tables where table_schema = "database_name" and table_name like pattern;
      prepare statement from @drop;
      execute statement;
    end //
    delimiter ;
    

    将 database_name 替换为数据库的名称(需要写入权限)。 要删除模式为 XYZ 的表,请调用输入为 XYZ 后跟通配符的过程,如下所示:

    call droplike("XYZ%");
    

    【讨论】:

    • 一些 SQL 方言允许像这样以逗号分隔的列表:DROP TABLE "table1_bits" , "table2_links" , "table3_stuff" ;
    【解决方案4】:

    这里有一些不错的整洁解决方案。但我所做的只是:

    SHOW TABLES LIKE 'migrate%';
    

    在 MySQL 工作台中。

    然后我将结果复制到一个像样的文本编辑器中,而不是使用转义序列查找/替换,并将\n 替换为;\nDROP TABLE,并整理了开始和结束。然后复制回 MySQL 工作台。比一些建议的解决方案更手动且不那么优雅,但实际上一样快。

    【讨论】:

      【解决方案5】:

      我认为你不能在 MySql 中删除多个数据库。

      但我有一个非常令人讨厌的解决方案。您可以使用 C/C++/C#/JAVA 编程,将“DROP DATABASE WHATEVER_<name>;”多次打印到记事本或任何文本编辑器中。之后,您可以在 MySql 的客户端命令提示符中复制粘贴,然后就可以了。不要忘记每个DROP 命令后的“;”。

      我相信这是可能的。试着写这个。

      【讨论】:

        【解决方案6】:

        这个(Jython)怎么样?

        rs = stmt.executeQuery( "SHOW DATABASES LIKE 'Whatever_%'" )
        databases_for_dropping = []
        while rs.next():
          databases_for_dropping.append( rs.getString( 1 ))
        for database_for_dropping in databases_for_dropping:
          stmt.execute( "DROP DATABASE %s" % database_for_dropping ) 
        

        【讨论】:

          【解决方案7】:

          如果有人正在寻找一个反映 scraimerExplorer 的简单答案,但它是使用 JDBC 用 Ja​​va 编写的(我知道我是这样的),这里有一个快速一个为我完成工作的肮脏的人:

          import java.sql.Connection;
          import java.sql.DriverManager;
          import java.sql.PreparedStatement;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          import java.util.ArrayList;
          
          public class DatabaseDeleter {
              // Pass your database wildcard as the only argument to program ( "%MY_CRAZY_PATTERN%")
              public void main(String[] args) throws SQLException, ClassNotFoundException{
          
                  Class.forName("com.mysql.jdbc.Driver");
                  Connection connection = DriverManager.getConnection("jdbc:mysql://databaseURL");
                  PreparedStatement pst = connection.prepareStatement("show databases like ?");
                  pst.setString(1, args[0]);
                  ResultSet rs = pst.executeQuery();
          
                  ArrayList<String> databases = new ArrayList<String>();
                  while (rs.next()) databases.add(rs.getString(1));
          
                  for (String s : databases){
                      Statement st = connection.createStatement();
                      st.execute("drop database " + s);
                  }
                  connection.close();
              }
          }
          

          警告:如果您不希望自己的 SQL 服务器遭到洗劫,请勿向客户甚至其他开发人员透露此信息。

          【讨论】:

            【解决方案8】:

            抱歉,我们不能使用 sql 命令一次删除多个数据库

            【讨论】:

              【解决方案9】:

              你可以试试mysql 5 general purpose routine library (可从here 下载)。使用它,您可以删除与正则表达式匹配的多个表。我建议仔细检查正则表达式,以防止删除您确实需要的表。

              【讨论】:

              • 我认为您没有阅读整个问题。他想删除多个“数据库”而不是多个“表”。
              【解决方案10】:
              DROP DATABASE `any-database_name`;
              

              我只是在我的数据库名称前后使用这个字符 `(反引号)。

              【讨论】:

                【解决方案11】:

                使用

                DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
                

                声明为described here

                我不知道你是否可以使用通配符来做类似的事情

                DROP DATABASE Whatever_%
                

                但我认为你应该尝试一下。

                【讨论】:

                • #1008 - 无法删除数据库“whatever_%”;数据库不存在,它只适用于 SELECT
                猜你喜欢
                • 2012-10-03
                • 2020-09-06
                • 2011-06-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-07-01
                • 2022-01-19
                • 1970-01-01
                相关资源
                最近更新 更多