mysql - 将 bash 变量应用于 mysql 插入语句 - 对某些人有效,但对其他人无效

标签 mysql linux bash

我一直在尝试整理来 self 的开发 CentOS 7 服务器和开发 mysql 8.0 数据库的信息,并将它们输入到一个单独的数据库/表中,以供监控仪表板读取。目前,我正在尝试检索 mysql 中每个数据库的所有表存储大小,并将数据输入到单独的表中。

我在使用 bash 变量保存数据库名称时遇到了问题。对于某些数据库名称,它工作得很好,但对于其他数据库名称,即使使用相同的语法,我也遇到了问题。

我一直在运行“TableStorage”函数来执行 insert into select 语句来填充我的 TABLE_STORAGE 监控表(见下文)

function TableStorage {
    DB1='database1'
    DB2='database2'
    mysql -u $DBA_USER -p$DBA_PASS <<EOF
        INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
            FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$DB1' ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;
        INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
            FROM information_schema.TABLES WHERE TABLE_SCHEMA = '$DB2' ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC;

        COMMIT;
    EOF
}

但是,当我运行上述函数时,仅将“database1”中的表信息插入到“database1”和“database2”中,而不是同时插入“database1”和“database2”。 我可以确认两个数据库都有多个表,因此数据并不存在。 即使我只运行了使用函数插入“database2”中的表的插入语句,我仍然没有运气。 我还在 mysql 中手动运行了上述两条语句,并且所有表都是以这种方式插入的,只是在函数中运行时没有这样做。

我还仔细检查了以下内容: -db 存在 - 存在表格 -bash 变量已设置 -在 bash 中回显整个语句以确保变量正确填充插入语句(它们确实如此)

真的很难过这个问题,我可以想象这是一个我错过的非常愚蠢的错误。任何帮助,将不胜感激。

最佳答案

带有准备好的语句的示例:

#!/usr/bin/env bash

TableStorage() {
  [ "$#" -ne 2 ] && return 1 # Two database-name arguments required

  mysql -u "$DBA_USER" -p "$DBA_PASS" <<EOF
    PREPARE stmt1 FROM 'INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024)
    FROM information_schema.TABLES WHERE TABLE_SCHEMA = @db ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC';

    SET @db="$1";
    EXECUTE stmt1 USING @db;
    SET @db="$2";
    EXECUTE stmt1 USING @db;
    COMMIT;
    DEALLOCATE PREPARE stmt1;
EOF
}

if TableStorage 'database1' 'database2'; then
  echo "TableStorage ok"
else
  echo "Failure to run TableStorage" >&2
fi

或者使用任意数量的数据库名称:

#!/usr/bin/env bash

TableStorage() {

  # Block to compose the SQL commands stream
  {
    # Prepare a statement
    echo "PREPARE stmt1 FROM 'INSERT INTO splunk.TABLE_STORAGE (TABLE_SCHEMA, TABLE_NAME, SIZE_MB) SELECT TABLE_SCHEMA, TABLE_NAME, ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024) FROM information_schema.TABLES WHERE TABLE_SCHEMA = @db ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC';"

    # While there is a database name argument
    while [ "$#" -gt 0 ]; do
      # Set SQL variable @db to database name argument $1
      # and execute the prepared statement
      printf 'SET @db="%s";\nEXECUTE stmt1 USING @db;\n' "$1"
      # Shift to next argument $1
      shift
    done
    # Commit the changes
    echo "COMMIT;"
    # Dispose of the prepared statement
    echo "DEALLOCATE PREPARE stmt1;"
  } |
    # Pipe the SQL commands to MySQL
    mysql -u "$DBA_USER" -p "$DBA_PASS"
}

if TableStorage 'database1' 'database2'; then
  echo "TableStorage ok"
else
  echo "Failure to run TableStorage" >&2
fi

关于mysql - 将 bash 变量应用于 mysql 插入语句 - 对某些人有效,但对其他人无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59359723/

相关文章:

php - 看不到基于alpine linux的wordpress docker容器的启动安装页面

linux - 如何从多个文件中获取特定文件结果的行号

php - 我如何在 php 中每 3 个月运行一次从开始日期到结束日期的循环

mysql - Rails 3 - increment_counter 递增两次

mysql - 如何根据 JSON 中的名称将 ID 号从 Angular 传递到 Spring

Linux weka 和大文件

linux - Bash find- 显示文件但未返回此类文件或目录

bash - 使大型光栅文件中除一个以外的所有值都为 0

linux - 如何使用新名称制作文件的副本,并在文件名中包含原始文件的时间戳?

html - 在 Mac 上使用 Bash 使用默认浏览器打开 .html 文件