MYSQL 安全添加/移除column 脚本

本文介绍了一种通过存储过程及动态SQL实现数据库表字段的安全添加与删除方法。具体包括利用存储过程判断字段是否存在并据此执行添加操作,以及通过判断来决定是否执行删除操作。适用于有权限限制的场景。

1. 如果不存在,就添加;

 用存储过程解决,定义成模板,可以通用;
 应用场景:必须拥有创建存储过程的权限
DELIMITER $$

USE `ebt_shop_test`$$
DROP PROCEDURE IF EXISTS `addFieldIfNotExists`$$
DROP FUNCTION IF EXISTS `isFieldExisting`$$

CREATE FUNCTION isFieldExisting (
 table_name_IN VARCHAR(100),
 field_name_IN VARCHAR(100)
 )
RETURNS INT
RETURN (
    SELECT COUNT(COLUMN_NAME)
    FROM INFORMATION_SCHEMA.columns
    WHERE TABLE_SCHEMA = DATABASE()
    AND TABLE_NAME = table_name_IN
    AND COLUMN_NAME = field_name_IN
)
$$

CREATE PROCEDURE addFieldIfNotExists (
 IN table_name_IN VARCHAR(100),
 IN field_name_IN VARCHAR(100),
 IN field_definition_IN VARCHAR(100)
 )
BEGIN
    SET @isFieldThere = isFieldExisting(table_name_IN, field_name_IN);    
    IF (@isFieldThere = 0) THEN  
        SET @ddl = CONCAT('ALTER TABLE ', table_name_IN);
        SET @ddl = CONCAT(@ddl, '', 'ADD COLUMN') ;
        SET @ddl = CONCAT(@ddl, '', field_name_IN);
        SET @ddl = CONCAT(@ddl, '', field_definition_IN);
        PREPARE stmt FROM @ddl;
       EXECUTE stmt;
       DEALLOCATE PREPARE stmt;
    END IF;
END$$

DELIMITER ;

【说明】使用了 “DELIMITER $$ … … DELIMITER ;” 分块语法,在此定义区域内的语句作为整体一并提交给服务器
调用添加列,例如:

-- call procedure add field if not exists

CALL addFieldIfNotExists ('dic_data', 'parentId', 'VARCHAR(50) NULL COMMENT \'父ID\'');

-- clean work
DROP PROCEDURE IF EXISTS `addFieldIfNotExists`;
DROP FUNCTION IF EXISTS `isFieldExisting`;

2.另一种方式: 如果不存在,就添加

如果没有权限创建函数和存储过程时,一种更直接的方式,直接写可执行的sql语句编译执行
应用场景:有受权限限制,每次都直接编写相应的SQL语句即可

SET @exeResult = (SELECT IF( (SELECT COUNT(*)
   FROM INFORMATION_SCHEMA.COLUMNS
   WHERE table_schema = DATABASE()
   AND table_name = 'dic_data'
   AND column_name = 'isLeaf1'
   ) > 0,
   'SELECT 1 AS RESULT',
   'alter table dic_data add column isLeaf1 char(1) COMMENT \'是否为叶子节点\' NULL after parentId'
     )
);
PREPARE stmt FROM @exeResult;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

【语法解析】:
@exeResult: 临时变量定义的方式
IF(boolean表达式, param1,param2):相当于程序中的三元表达式
PREPARE :预编译SQL语句
EXECUTE :执行SQL语句
DEALLOCATE :清除预编译的语句
eg:

PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
SET @a = 3;
SET @b = 4;
EXECUTE stmt1 USING @a, @b;
DEALLOCATE PREPARE stmt1;

3.安全地删除列,也可以先进行判断而后进行操作

SET @exeResult = (SELECT IF( (SELECT COUNT(*)
   FROM INFORMATION_SCHEMA.COLUMNS
   WHERE table_schema = DATABASE()
   AND table_name = 'dic_data'
   AND column_name = 'isLeaf1'
   ) > 0,
   'alter table dic_data drop column isLeaf1',
   'SELECT 0 AS RESULT'
     )
);
PREPARE stmt FROM @exeResult;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

步骤 3:初始化 MySQL 元数据 Bash cd /export/server/hive bin/schematool -initSchema -dbType mysql -verbose SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/export/server/hive/lib/log4j-slf4j-impl-2.18.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/export/server/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] Beeline version 4.0.0 by Apache Hive beeline> !quit [root@master hive]# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 125 Server version: 5.7.43 MySQL Community Server (GPL) Copyright (c) 2000, 2023, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> CREATE DATABASE IF NOT EXISTS hive CHARACTER SET utf8 COLLATE utf8_general_ci; Query OK, 1 row affected, 1 warning (0.00 sec) mysql> GRANT ALL PRIVILEGES ON hive.* TO 'root'@'%' IDENTIFIED BY '123456'; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec) mysql> EXIT; Bye [root@master hive]# vim /export/server/hive/conf/hive-site.xml -bash: vim: 未找到命令 [root@master hive]# vi /export/server/hive/conf/hive-site.xml [root@master hive]# cd /export/server/hive [root@master hive]# bin/schematool -initSchema -dbType mysql -verbose SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/export/server/hive/lib/log4j-slf4j-impl-2.18.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/export/server/hadoop/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory] Initializing the schema to: 4.0.0 Metastore connection URL: jdbc:mysql://192.168.128.130:3306/hive?createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8 Metastore connection Driver : com.mysql.jdbc.Driver Metastore connection User: root Starting metastore schema initialization to 4.0.0 Initialization script hive-schema-4.0.0.mysql.sql Connecting to jdbc:mysql://192.168.128.130:3306/hive?createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8 Connected to: MySQL (version 5.7.43) Driver: MySQL Connector Java (version mysql-connector-java-5.1.32 ( Revision: jess.balint@oracle.com-20140716155848-mlwabor66widht1n )) Transaction isolation: TRANSACTION_READ_COMMITTED 0: jdbc:mysql://192.168.128.130:3306/hive> !autocommit off Autocommit status: false 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */ No rows affected (0.017 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */ No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */ No rows affected (0.008 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET NAMES utf8 */ No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */ No rows affected (0.002 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40103 SET TIME_ZONE='+00:00' */ No rows affected (0.007 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */ No rows affected (0.008 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */ No rows affected (0.002 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */ No rows affected (0.006 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */ No rows affected (0.003 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @saved_cs_client = @@character_set_client */ No rows affected (0.005 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = utf8 */ No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> CREATE TABLE IF NOT EXISTS `BUCKETING_COLS` ( `SD_ID` bigint(20) NOT NULL, `BUCKET_COL_NAME` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, `INTEGER_IDX` int(11) NOT NULL, PRIMARY KEY (`SD_ID`,`INTEGER_IDX`), KEY `BUCKETING_COLS_N49` (`SD_ID`), CONSTRAINT `BUCKETING_COLS_FK1` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 No rows affected (0.074 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = @saved_cs_client */ No rows affected (0.005 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @saved_cs_client = @@character_set_client */ No rows affected (0.007 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = utf8 */ No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> CREATE TABLE IF NOT EXISTS `CDS` ( `CD_ID` bigint(20) NOT NULL, PRIMARY KEY (`CD_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 No rows affected (0.01 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = @saved_cs_client */ No rows affected (0.003 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @saved_cs_client = @@character_set_client */ No rows affected (0.003 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = utf8 */ No rows affected (0.005 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> CREATE TABLE IF NOT EXISTS `COLUMNS_V2` ( `CD_ID` bigint(20) NOT NULL, `COMMENT` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, `COLUMN_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, `TYPE_NAME` MEDIUMTEXT DEFAULT NULL, `INTEGER_IDX` int(11) NOT NULL, PRIMARY KEY (`CD_ID`,`COLUMN_NAME`), KEY `COLUMNS_V2_N49` (`CD_ID`), CONSTRAINT `COLUMNS_V2_FK1` FOREIGN KEY (`CD_ID`) REFERENCES `CDS` (`CD_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = @saved_cs_client */ No rows affected (0.007 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET @saved_cs_client = @@character_set_client */ No rows affected (0.003 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = utf8 */ No rows affected (0.004 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> CREATE TABLE IF NOT EXISTS `DATABASE_PARAMS` ( `DB_ID` bigint(20) NOT NULL, `PARAM_KEY` varchar(180) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, `PARAM_VALUE` varchar(4000) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, PRIMARY KEY (`DB_ID`,`PARAM_KEY`), KEY `DATABASE_PARAMS_N49` (`DB_ID`), CONSTRAINT `DATABASE_PARAMS_FK1` FOREIGN KEY (`DB_ID`) REFERENCES `DBS` (`DB_ID`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 No rows affected (0.007 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> /*!40101 SET character_set_client = @saved_cs_client */ No rows affected (0.007 seconds) 0: jdbc:mysql://192.168.128.130:3306/hive> CREATE TABLE `CTLGS` ( `CTLG_ID` BIGINT PRIMARY KEY, `NAME` VARCHAR(256), `DESC` VARCHAR(4000), `LOCATION_URI` VARCHAR(4000) NOT NULL, `CREATE_TIME` INT(11), UNIQUE KEY `UNIQUE_CATALOG` (`NAME`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 Error: Table 'ctlgs' already exists (state=42S01,code=1050) Closing: 0: jdbc:mysql://192.168.128.130:3306/hive?createDatabaseIfNotExist=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8 Schema initialization FAILED! Metastore state would be inconsistent! Underlying cause: java.io.IOException : Schema script failed, errorcode 2 org.apache.hadoop.hive.metastore.HiveMetaException: Schema initialization FAILED! Metastore state would be inconsistent! at org.apache.hadoop.hive.metastore.tools.schematool.SchemaToolTaskInit.execute(SchemaToolTaskInit.java:66) at org.apache.hadoop.hive.metastore.tools.schematool.MetastoreSchemaTool.run(MetastoreSchemaTool.java:484) at org.apache.hive.beeline.schematool.HiveSchemaTool.main(HiveSchemaTool.java:143) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.util.RunJar.run(RunJar.java:323) at org.apache.hadoop.util.RunJar.main(RunJar.java:236) Caused by: java.io.IOException: Schema script failed, errorcode 2 at org.apache.hive.beeline.schematool.HiveSchemaTool.execSql(HiveSchemaTool.java:110) at org.apache.hive.beeline.schematool.HiveSchemaTool.execSql(HiveSchemaTool.java:88) at org.apache.hadoop.hive.metastore.tools.schematool.SchemaToolTaskInit.execute(SchemaToolTaskInit.java:62) ... 8 more *** schemaTool failed ***
最新发布
11-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值