如何从数据库转储单个存储过程

BAL*_*ALA 6 mysql mysqldump backup stored-procedures

我需要创建一个转储文件,其中包含来自数据库的单个存储过程,而不是所有例程。

我试过这样的事情:

mysqldump -u root -pssmart --skip-triggers --no-create-info --no-data \
    --no-create-db --skip-opt test_fshop SP_ITEM_SALES_REPORT -R \
    > test_fshop_routines.sql 
Run Code Online (Sandbox Code Playgroud)

test_fshop是我的数据库名称,SP_ITEM_SALES是我的 SP。我想要我的 SP 作为 .sql 文件。

Rol*_*DBA 5

坏消息

您不能使用 mysqldump 来执行此操作。

好消息

您可以使用 mysql 客户端。首先,找出存储过程是否存在。如果是,则获取它是(PROCEDUREFUNCTION)的程序类型。然后,SHOW CREATE为存储过程发出。您将不得不剥离顶部 3 行和底部 3 行:

DBNAME=${1}
SPNAME=${2}
SPFILE=${DBNAME}_${SPNAME}.sql
SPTEMP=${DBNAME}_${SPNAME}.tmp
MYSQL_CONN="-u... -p..."
SQLSTMT="SELECT COUNT(1) FROM mysql.proc WHERE db='${DBNAME}' AND name='${SPNAME}'"
PROC_EXISTS=`mysql ${MYSQL_CONN} -ANe"${SQLSTMT}" | awk '{print $1}'`
if [ ${PROC_EXISTS} -eq 1 ]
then
    SQLSTMT="SELECT type FROM mysql.proc WHERE db='${DBNAME}' AND name='${SPNAME}'"
    PROC_TYPE=`mysql ${MYSQL_CONN} -ANe"${SQLSTMT}" | awk '{print $1}'`
    SQLSTMT="SHOW CREATE ${PROC_TYPE} ${DBNAME}.${SPNAME}\G"
    mysql ${MYSQL_CONN} -ANe"${SQLSTMT}" > ${SPFILE}

    #
    # Remove Top 3 Lines
    #
    LINECOUNT=`wc -l < ${SPFILE}`
    (( LINECOUNT -= 3 ))
    tail -${LINECOUNT} < ${SPFILE} > ${SPTEMP}

    #
    # Remove Bottom 3 Lines
    #
    LINECOUNT=`wc -l < ${SPTEMP}`
    (( LINECOUNT -= 3 ))
    head -${LINECOUNT} < ${SPTEMP} > ${SPFILE}
else
    echo "Stored Procedure ${DBNAME}.${SPNAME} Does Not Exist"
fi
rm -f ${SPTEMP}
Run Code Online (Sandbox Code Playgroud)

这是一个示例运行:

[root@***]# ./GetMyProc.sh common DMSPushers
[root@***]# cat common_DMSPushers.sql
CREATE DEFINER=`pma`@`10.%` PROCEDURE `DMSPushers`()
BEGIN

  DECLARE cntr INT DEFAULT 0;
  DECLARE dealerName VARCHAR(50);
  DECLARE dealerID INT;

  DECLARE done boolean DEFAULT false;
  DECLARE dealers CURSOR FOR SELECT bdd.dealer_id, ta.name FROM `b_dealer__dmsaccount` bdd left join t_dmsaccount ta on bdd.dmsaccount_id = ta.id where ta.dms_type = 1 order by bdd.dealer_id desc;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := true;

  OPEN dealers;

  read_loop: LOOP
        FETCH dealers INTO dealerID, dealerName;
        SET cntr = cntr + 1;

    IF done OR cntr > 200 THEN
      LEAVE read_loop;
    END IF;

        IF dealerID > 0 AND dealerID < 664 THEN
                IF dealerName IS NULL THEN
                        SET dealerName = '';
                END IF;
                SET dealerName = REPLACE(dealerName,'''','''''');

                -- Does the Database even exist???
                SET @query = CONCAT('SELECT COUNT(SCHEMA_NAME) FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ''D',dealerID,''' INTO @schemaExists');
                PREPARE stmt1 FROM @query;
                EXECUTE stmt1;

                IF @schemaExists > 0 THEN
                        SET @query = CONCAT('INSERT dealers_that_push (dealerID, dealerName, pushDate) SELECT ', dealerID, ',''', dealerName ,''',date FROM D',dealerID,'.contactLog where message like ''%pushed to the DMS%''');
                        PREPARE stmt1 FROM @query;
                        EXECUTE stmt1;
                END IF;

        END IF;

  END LOOP;

  CLOSE dealers;
END
[root@***]#
Run Code Online (Sandbox Code Playgroud)

好消息

这是一个脚本,它将每个存储过程转储到单独的 SQL 文件中:

MYSQL_CONN="-u... -p..."
SQLSTMT="SELECT COUNT(1) FROM mysql.proc"
PROCCOUNT=`mysql ${MYSQL_CONN} -ANe"${SQLSTMT}" | awk '{print $1}'`
if [ ${PROCCOUNT} -eq 0 ] ; then exit ; fi
SPLIST=""
for DBSP in `mysql ${MYSQL_CONN} -ANe"SELECT CONCAT(type,'@',db,'.',name) FROM mysql.proc"`
do
    SPLIST="${SPLIST} ${DBSP}"
done
for TYPEDBSP in `echo "${SPLIST}"`
do
    DB=`echo "${TYPEDBSP}" | sed 's/@/ /' | sed 's/\./ /' | awk '{print $2}'`
    SP=`echo "${TYPEDBSP}" | sed 's/@/ /' | sed 's/\./ /' | awk '{print $3}'`
    SQLSTMT=`echo "SHOW CREATE ${TYPEDBSP}\G" | sed 's/@/ /'`
    SPFILE=${DB}_${SP}.sql
    SPTEMP=${DB}_${SP}.tmp
    echo Echoing ${SQLSTMT} into ${SPFILE}
    mysql ${MYSQL_CONN} -ANe"${SQLSTMT}" > ${SPFILE}
    #
    # Remove Top 3 Lines
    #
    LINECOUNT=`wc -l < ${SPFILE}`
    (( LINECOUNT -= 3 ))
    tail -${LINECOUNT} < ${SPFILE} > ${SPTEMP}
    #
    # Remove Bottom 3 Lines
    #
    LINECOUNT=`wc -l < ${SPTEMP}`
    (( LINECOUNT -= 3 ))
    head -${LINECOUNT} < ${SPTEMP} > ${SPFILE}
    rm -f ${SPTEMP}
done
ls -l
Run Code Online (Sandbox Code Playgroud)

试一试 !!!