mysql命令行創建存儲過程,mysqldump導出存儲過程;


 

 http://my.oschina.net/zerotime/blog/113126

Mysql命令行創建存儲過程時,首先要輸入分隔符

DELIMITER // 
CREATE PROCEDURE proc () 
begin 
…… 
end 
// 
OK,可以創建完成了。

顯示存儲過程命令

show create procedure 存儲過程名;

刪除存儲過程命令

drop procedure 存儲過程名;

 

 

 

 

http://database.51cto.com/art/201011/235017.htm

MYSQL命令行的使用是學習MYSQL數據庫過程中的基礎知識,那么應該如何用MYSQL命令行創建存儲過程呢?

也嘗試了一些方法,但是第一個分號mysql就以為語句結束了,就舉個例子來說:

  1. CREATE PROCEDURE p7 (IN b INTEGER(12))  
  2.  
  3. begin  
  4.  
  5. declare a INTEGER(12);  
  6.  
  7. set a=5;  
  8.  
  9. INSERT INTO t VALUES (a);  
  10.  
  11. SELECT s1*a FROM t WHERE b<=s1;  
  12.  
  13. End  
  14.  

這個存儲過程,在命令行直接創建的話,在第三排你輸入分號后就報錯了……因為MYSQL以為這個語句結束了,那對於MYSQL而言

  1. CREATE PROCEDURE p7 (IN b INTEGER(12))  
  2.  
  3. begin  
  4.  
  5. declare a INTEGER(12);  
  6.  

肯定是個錯誤語句。

然后看了些東西,原來要加分隔符- -……….

  1. DELIMITER //  
  2.  
  3. CREATE PROCEDURE p7 (IN b INTEGER(12))  
  4.  
  5. begin  
  6.  
  7. declare a INTEGER(12);  
  8.  
  9. set a=5;  
  10.  
  11. INSERT INTO t VALUES (a);  
  12.  
  13. SELECT s1*a FROM t WHERE b<=s1;  
  14.  
  15. End  
  16.  
  17. //  
  18.  

就OK了…………意思就是說在//……//之間的當成一個語句執行所以MYSQL接到的才是這個存儲過程完整的創建語句。

http://zhuixue.iteye.com/blog/375353

查詢數據庫中的存儲過程

 

方法一:

       select `name` from mysql.proc where db = 'your_db_name' and `type` = 'PROCEDURE'

 

方法二:

         show procedure status;

 

 

查看存儲過程或函數的創建代碼

 

show create procedure proc_name;
show create function func_name;

http://www.111cn.net/database/mysql/35817.htm

方法一:(直接查詢)

select `specific_name` from mysql.proc where db = 'your_db_name' and `type` = 'procedure'

方法二:(查看數據庫里所有存儲過程+內容)

show procedure status;

方法三:(查看當前數據庫里存儲過程列表)

select specific_name from mysql.proc ;

方法四:(查看某一個存儲過程的具體內容)

select body from mysql.proc where specific_name = 'your_proc_name';

查看存儲過程或函數的創建代碼 :

show create procedure your_proc_name;
show create function your_func_name;

刪除存儲過程:

drop procedure your_proc_name;

=============

http://543197.blog.51cto.com/533197/114141

文章引用:

[url]http://bbs.tarena.com.cn/viewthread.phptid=166328[/url]

MySQL 存儲過程是從 MySQL 5.0 開始增加的新功能。存儲過程的優點有一籮筐。不過最主要的還是執行效率和SQL 代碼封裝。特別是 SQL 代碼封裝功能,如果沒有存儲過程,在外部程序訪問數據庫時(例如 PHP),要組織很多 SQL 語句。特別是業務邏輯復雜的時候,一大堆的 SQL 和條件夾雜在 PHP 代碼中,讓人不寒而栗。現在有了 MySQL 存儲過程,業務邏輯可以封裝存儲過程中,這樣不僅容易維護,而且執行效率也高。 一、MySQL 創建存儲過程 
“pr_add” 是個簡單的 MySQL 存儲過程,這個存儲過程有兩個 int 類型的輸入參數 “a”、“b”,返回這兩個參數的和。 
drop procedure if exists pr_add;
-- 計算兩個數之和
create procedure pr_add
(
   a int,
   b int
)
begin
   declare c int;
   if a is null then
      set a = 0;
   end if;
   if b is null then
      set b = 0;
   end if;
   set c = a + b;
   select c as sum;
   /*
   return c; -- 不能在 MySQL 存儲過程中使用。return 只能出現在函數中。
   */
end;
二、調用 MySQL 存儲過程 
call pr_add(10, 20);
執行 MySQL 存儲過程,存儲過程參數為 MySQL 用戶變量。 
set @a = 10;
set @b = 20;
call pr_add(@a, @b);
三、MySQL 存儲過程特點 
創建 MySQL 存儲過程的簡單語法為: 
create procedure 存儲過程名字()
(
   [in|out|inout] 參數 datatype
)
begin
   MySQL 語句;
end;
MySQL 存儲過程參數如果不顯式指定“in”、“out”、“inout”,則默認為“in”。習慣上,對於是“in” 的參數,我們都不會顯式指定。 
1. MySQL 存儲過程名字后面的“()”是必須的,即使沒有一個參數,也需要“()” 
2. MySQL 存儲過程參數,不能在參數名稱前加“@”,如: “@a int”。下面的創建存儲過程語法在 MySQL 中是錯誤的(在 SQL Server 中是正確的)。 MySQL 存儲過程中的變量,不需要在變量名字前加“@”,雖然 MySQL 客戶端用戶變量要加個“@”。 
create procedure pr_add
(
   @a int,  -- 錯誤
   b int    -- 正確
)
3. MySQL 存儲過程的參數不能指定默認值。 
4. MySQL 存儲過程不需要在 procedure body 前面加 “as”。而 SQL Server 存儲過程必須加 “as” 關鍵字。 
create procedure pr_add
(
   a int,
   b int
)
as              -- 錯誤,MySQL 不需要 “as”
begin
   mysql statement ...;
end;
5. 如果 MySQL 存儲過程中包含多條 MySQL 語句,則需要 begin end 關鍵字。 
create procedure pr_add
(
   a int,
   b int
)
begin
   mysql statement 1 ...;
   mysql statement 2 ...;
end;
6. MySQL 存儲過程中的每條語句的末尾,都要加上分號 “;” 
   ...
   declare c int;
   if a is null then
      set a = 0;
   end if;
   ...
end;
7. MySQL 存儲過程中的注釋。 
   /*
     這是個
     多行 MySQL 注釋。
   */
   declare c int;     -- 這是單行 MySQL 注釋 (注意 -- 后至少要有一個空格)
   if a is null then  # 這也是個單行 MySQL 注釋
      set a = 0;
   end if;
   ...
end;
8. 不能在 MySQL 存儲過程中使用 “return” 關鍵字。 
   set c = a + b;
   select c as sum;
   /*
   return c; -- 不能在 MySQL 存儲過程中使用。return 只能出現在函數中。
   */
end;
9. 調用 MySQL 存儲過程時候,需要在過程名字后面加“()”,即使沒有一個參數,也需要“()” 
call pr_no_param();
10. 因為 MySQL 存儲過程參數沒有默認值,所以在調用 MySQL 存儲過程時候,不能省略參數。可以用 null 來替代。 
call pr_add(10, null);

===================================================

http://www.cnblogs.com/gaizai/archive/2013/03/15/2961868.html

一.本文所涉及的內容(Contents)

  1. 本文所涉及的內容(Contents)
  2. 背景(Contexts)
  3. 設計思路(Design)
  4. 遷移自動化特點(Points)
  5. 實現代碼(SQL Codes)
  6. 參考文獻(References)

二.背景(Contexts)

  之前我寫過關於SQL Server的數據遷移自動化的文章:SQL Server 數據庫遷移偏方,在上篇文章中設計了一張臨時表,這個臨時表記錄搬遷的配置信息,用一個存儲過程讀取這張表進行數據的遷移,再由一個Job進行迭代調用這個存儲過程。

  在這次MySQL的實戰中,我的數據庫已經做了4個分片,分布在不同的4台機器上,每台機器上的數據量有1.7億(1.7*4=6.8億),占用空間260G(260*4=1040G),這次遷移的目的就是刪除掉一些歷史記錄,減輕數據庫壓力,有人說這為什么不使用表分區呢?這跟我們的業務邏輯有關造成無法使用表分區,至於為什么,參考閱讀:MySQL表分區實戰,其中最重要就是唯一索引的問題,擴展閱讀:MySQL當批量插入遇上唯一索引,這篇文章需要了解MySQL的定時器的一些知識:MySQL定時器Events

  本文與SQL Server 數據庫遷移偏方最大的不同就是MySQL的Events不是串行執行的,當作業調用的存儲過程還沒有執行完畢,但又到了調度的時間,MySQL不會等待上次作業完成之后再調度,所以會造成重復調用讀取到相同的數據;而SQL Server並不存在上面的問題。

三.設計思路(Design)

1. 創建一個臨時表TempBlog_Log,這個表用於保存每次轉移數據的ID起始值和結束值,以及搬遷的開始時間和結束時間;(這個ID是我們要遷移表的主鍵,自增字段,唯一標識)

2. 創建一個存儲過程InsertData(),這個存儲過程用於在TempBlog_Log表中插入記錄,創建這個存儲過程是因為MySQL跟SQL Server有些不同,MySQL不支持匿名存儲過程,SQL Server直接執行SQL就可以了,無需為這些SQL再創建一個存儲過程,這就是匿名存儲過程了;

3. 創建一個存儲過程MoveBlogData(),這個存儲過程用於在TempBlog_Log表中讀取記錄,再批量把BlogA數據轉移到BlogB中;這個是核心邏輯,解決了定時器重復調度的問題,詳情見代碼的解釋;

4. 創建一個定時器e_Blog, 這個定時器定時調用存儲過程MoveBlogData(),但是這里存在重復調度的問題,只能通過存儲過程MoveBlogData()進行控制。

四.遷移自動化特點(Points)

1. 該設計適應於大數據的遷移;

2. 可以最小化宕機時間(在轉移的過程中BlogA還是一直在進數據的,只是在最后一部分數據的時候需要短時間的停入庫操作);

3. 可以防止MySQL定時器重復執行所帶來的問題;

4. 可以實時監控數據轉移的進度;

5. 數據遷移可能需要持續好幾天的時間,它能保證BlogB的數據會無限的接近BlogA的數據;

五.實現代碼(SQL Codes)

(一) 創建臨時表TempBlog_Log

復制代碼
-- 創建表
CREATE TABLE TempBlog_Log(
    BeginId INT NOT NULL,
    EndId INT NOT NULL,
    IsDone BIT DEFAULT b'0' NOT NULL,
    BeginTime DATETIME DEFAULT NULL,
    EndTime DATETIME DEFAULT NULL,
PRIMARY KEY(BeginId) 
);
復制代碼

下面就對表結構進行字段解釋:

1) BeginId、EndId都是ServerA遷移表的主鍵值,BeginId表示一次數據遷移的起始值,EndId表示一次數據遷移的結束值,兩個值的差就是這次數據轉移的數據量;

2) IsDone 表示是否已經成功轉移數據;

3) BeginTime表示轉移的開始時間,EndTime表示轉移的結束時間,這兩個字段設置缺省值為NULL很關鍵,是后面進行判斷是否重復執行的依據;

 

(二) 創建存儲過程InsertData()

復制代碼
-- 存儲過程
DELIMITER $$
USE `DataBaseName`$$
DROP PROCEDURE IF EXISTS `InsertData`$$

CREATE DEFINER=`root`@`%` PROCEDURE `InsertData`()
BEGIN
    DECLARE ids_begin,ids_end,ids_increment INT;
    SET ids_begin=130000000;-- 需要轉移開始Id值
    SET ids_end=210000000;-- 需要轉移結束Id值
    SET ids_increment=200000;-- 每次轉移的Id量
    WHILE ids_begin < ids_end DO 
        INSERT INTO TempBlog_Log(BeginId,EndId) VALUES(ids_begin,ids_begin+ids_increment);
        SET ids_begin = ids_begin + ids_increment;
    END WHILE; 
END$$
    
DELIMITER ;
復制代碼

MySQL中不支持匿名存儲過程,所以為了在臨時表TempBlog_Log插入記錄,只能創建一個存儲過程了,如果你還沒寫過MySQL的存儲過程,那么這是一個很好的例子。

1) 為了能在存儲過程中使用MySQL的分隔符“;”,DELIMITER $$表示你以“$$”作為分隔符,你也可以使用“//”;

2) 定義變量時,你需要把所有的變量定義完了,之后再進行賦值,不然會報錯,這跟SQL Server是有區別的;

3) WHILE條件后面需要加DO,而且要以END WHILE;作為結束標記;

4) 作為存儲過程的結束,再次出現“$$”表示已經結束,跟上一個“$$”形成一個整體、過程,並重新設置“;”為分隔符;

5) 執行CALL InsertData();調用上面的存儲過程,插入數據,調用完畢的結果如下圖Figure1所示:

clip_image001

(Figure1:轉移前狀態)

 

(三) 創建保留數據的新表BlogB

  做完上面的准備工作,接下來就是創建與BlogA相同結構的BlogB表了,有些不同的就是不需要在BlogB創建太多的索引,只需要存儲兩個索引就可以了,一個是ID的聚集索引,一個是唯一索引(在批量插入的時候需要判重);

  上面索引是根據我業務上的需求決定的,你需要視情況而定;

 

(四) 創建存儲過程MoveBlogData()

復制代碼
DELIMITER $$
USE `DataBaseName`$$
DROP PROCEDURE IF EXISTS `MoveBlogData`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `MoveBlogData`()
BEGIN
    DECLARE blog_ids_begin INT;-- Id起始值
    DECLARE blog_ids_end INT;-- Id結束值
    DECLARE blog_ids_max INT;-- BlogA表現在的最大值
    DECLARE blog_begintime INT;-- 執行開始時間
    DECLARE blog_endtime INT;-- 執行結束時間
    -- 查詢TempBlog_Log表還沒有done的記錄
    SELECT BeginId,EndId,BeginTime,EndTime INTO blog_ids_begin,blog_ids_end,blog_begintime,blog_endtime FROM TempBlog_Log WHERE IsDone = 0 ORDER BY BeginId LIMIT 0,1;
    
    -- 防止了定時器的重復執行
    IF(blog_begintime IS NULL AND blog_endtime IS NULL) THEN
        -- 設置當前最大的Id值
        SELECT MAX(ids) INTO blog_ids_max FROM BlogA;
        -- 防止轉移超過當前最大值的Id數據
        IF(blog_ids_begin != 0 AND blog_ids_end != 0 AND blog_ids_max >= blog_ids_end) THEN
            -- 更新執行開始時間
            UPDATE TempBlog_Log SET BeginTime = NOW() WHERE BeginId = blog_ids_begin;
            -- 插入Id段數據,忽略重復值
            INSERT IGNORE INTO BlogB (ID,AuthorID,Content,QUOTE,QuoteID,Author,TIME,Url,ImageUrl,Transmits,Comments,HASH,Site,AuthorUID,TYPE,HotTopic,AddOn,QuoteAuthorID,IDs)
            SELECT ID,AuthorID,Content,QUOTE,QuoteID,Author,TIME,Url,ImageUrl,Transmits,Comments,HASH,Site,AuthorUID,TYPE,HotTopic,AddOn,QuoteAuthorID,IDs
                FROM BlogA WHERE IDs >= blog_ids_begin AND IDs < blog_ids_end;
            -- 更新執行結束時間
            UPDATE TempBlog_Log SET IsDone = 1,EndTime = NOW() WHERE BeginId = blog_ids_begin;
        END IF;
    END IF;
END$$

DELIMITER ;
復制代碼

這個存儲過程是整個搬遷數據的核心代碼,之所以說是核心,是因為它把比較多的細節考慮進去,基本上實現自動化的目的。

1) 代碼中IF(blog_begintime IS NULL AND blog_endtime IS NULL) 防止了定時器的重復執行,兩個值都為NULL的時候表示這個Id段的數據還沒有被轉移,這樣就可以跳過,不執行下面的邏輯;

2) 查詢BlogA的最大值可以防止轉移超過當前BlogA最大值的Id數據,只有當blog_ids_max>=blog_ids_end才符合轉移的條件;

3) 在MySQL中對唯一索引約束的數據操作有很多的關鍵字支持,INSERT IGNORE INTO就是在批量插入過程中只插入沒有的數據,忽略重復的數據;更多唯一索引的信息:MySQL當批量插入遇上唯一索引

4) 查詢中FROM BlogA WHERE IDs >= blog_ids_begin AND IDs < blog_ids_end;需要注意IDs值的閉合關系,不然造成重復數據或者丟失數據;

 

(五) 創建定時器e_Blog

復制代碼
DELIMITER $$

CREATE DEFINER=`root`@`localhost` EVENT `e_blog` 
ON SCHEDULE EVERY 30 SECOND 
STARTS '2012-12-07 14:58:53' 
ON COMPLETION PRESERVE DISABLE 
DO CALL MoveBlogData()$$

DELIMITER ;
復制代碼

這定時器e_Blog的作用是在每隔30 SECOND調用一次存儲過程MoveBlogData(),至於有沒轉移數據那就是存儲過程判斷了,跟定時器的調度頻率完全沒有關系,更多關於定時器的信息:MySQL定時器Events

 

(六) 監控數據轉移的狀態

當定時器啟動后,可以查看TempBlog_Log表監控調度的進度:

clip_image002

(Figure2:轉移中狀態)

Figure2表示正在轉移Id>=225200000到Id<225400000這20W的數據;

你也可以通過下面的SQL進行統計:

SELECT IsDone,COUNT(1) FROM tempblog_log 
GROUP BY IsDone ORDER BY IsDone DESC;

 

(七) 創建索引

  創建保留數據的新表BlogB的時候不要創建不必要的索引,等轉移完數據之后再創建回相關的索引;這樣做的目的是在插入數據的時候不需要對索引進行維護,並且到轉移完之后再創建索引可以讓索引更加沒有索引碎片;

 

(八) 禁用定時器

  當TempBlog_Log表不再更新的時候,我們就可以禁用定時器了。因為BlogA表是一直在進數據的,所以當TempBlog_Log不再更新就說明數據已經基本轉移完畢了(新增的數據量小於20W),這個時候就可以禁用定時器了。

 

(九) 轉移最后數據

  首先停止對BlogA表的入庫操作,通過SQL轉移最后一部分的數據到BlogB中,轉移完之后修改表名就大功告成了。

六.參考文獻(References)

SQL Server 數據庫遷移偏方

MYSQL插入處理重復鍵值的幾種方法

 

=========================================================

http://liuer.blog.51cto.com/1519559/1084499

 
mysqldump--導出工具
 
#導出某個數據庫--結構+數據
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt db_name |gzip -9 > /db_bakup/db_name.gz
 
#導出某個數據庫的表--結構+數據+函數+存儲過程
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt -R db_name |gzip -9 > /db_backup/db_name.gz
 
#導出多個數據庫
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --databases db_name1 db_name2 db_name3 |gzip -9 > /db_backup/mul_db.gz 
 
#導出所有的數據庫
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --all-databases |gzip -9 > /db_bak/all_db.gz
 
#導出某個數據庫的結構
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --no-data db_name|gzip -9 > /db_bak/db_name.strcut.gz
 
#導出某個數據庫的數據
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --no-create-info db_name|gzip -9 > /db_bak/db_naem.data.gz
 
#導出某個數據庫的某張表
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt db_name tbl_name |gzip -9 > /db_bak/db_name.tal_name.gz
 
# 導出某個數據庫的某張表的結構
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --no-data db_name tal_name | gzip -9 > /db_bak/db_name.tal_name.struct.gz
 
#導出某個數據庫的某張表的數據
shell>mysqldump -h192.168.161.124 -uroot -pxxxxxx --opt --no-create-info db_name tbl_name | gzip -9 > /db_bak/db_name.tbl_name.data.gz
 
##--opt==--add-drop-table + --add-locks + --create-options + --disables-keys + --extended-insert + --lock-tables + --quick + --set+charset
##默認使用--opt,--skip-opt禁用--opt參數
--------------------------------------------------------------------------------
 
表結構等已經在目標數據庫中存在,不想拷貝數據庫過去,MySQL的存儲過程導出和導入,Mysqldump工具可以實現,具體用法為:
 ? [root@localhost bin]# mysqldump -uroot -p -hlocalhost -P3306 -n -d -t -R DBName > procedure_name.sql
參數說明:
-n: --no-create-db
-d: --no-data
-t: --no-create-info
-R: --routines Dump stored routines (functions and procedures)

Mysqldump是客戶端工具用來備份數據庫或在不同數據庫之間進行數據遷移。備份內容包含創建活裝載表的 SQL語句:
主要參數介紹:
1.連接選項
-u,--user=name
-p,--password=name
-h,--host=name
-P,--port=#
2.輸出內容選項
--add-drop-database
--add-drop-table
-n;--no-create-db
-d;--no-data
-t;--no-create-info
3.輸出格式選項
--compact
-c --complete-insert
-T(指定數據表中的數據備份為單純的數據文件和建表SQL兩個文件)
注意:xx.sql建表文件是以linux的root用戶創建,而xx.txt文件則是一linux的mysql用戶創建,因此這兩個文件的存放路徑一定要保證mysql用戶有讀寫創建文件的權限。
--fields-terminated-by=name(域分隔符)
--fields-enclosed-by=name(域引用符)
--fields-optionally-enclosed-by=name(域引用可選字符)
--fields-escaped-by=name(轉義字符)
4.字符集選項
--default--character-set=xx
5.其他選項
-F --flush-logs(備份前刷新日志)
-l --lock-tables(給所有的表加讀鎖)

http://www.netingcn.com/mysqldump-procedure.html

mysqldump是mysql自帶的一個備份數據庫的工具,使用mysqldump可以很方便的把已有的數據庫導出來,使用

mysqldump --help
如果MYSQL_HOME/bin沒有加入PATH,需要指定去路徑

可以看到有很多可選參數。

需要注意:默認情況下,mysqldump並不會導出數據庫的存儲過程和函數,如果數據庫上創建了存儲過程且備份是需要備份存儲過程,那就需要用參數 -R 來指定,例如:

mysqldump -u root -p passwd -R testDB > db.sql


http://www.2cto.com/database/201211/168571.html
4.如果需要導出mysql里面的函數或者存儲過程
      mysqldump -h  hostname -u  username   -ntd -R   databasename  > backupflie.sql  (包括存過過程和函數一次性完整導出)
     
        其中的 -ntd 是表示導出表結構和數據;-R是表示導出函數、存儲過程
 
     可以參照mysqldump --help
 
mysql常用導入數據的命令:
      my sql數據庫導入導出:
       mysqldump -u 用戶名 -p 數據庫名 > 數據庫名.sql
      如:
   mysqldump -u root   -p         testdb  > testdb.sql (不包括存儲過程和函數)
   mysqldump -u root   -p  -R   testdb  > testdb.sql (**包括存儲過程和函數**)
 
     MySQL source命令向數據庫中導入數據:
     mysql>use testdb;
    mysql>set names  utf8;
     mysql>source /tmp/bdc.sql;
 
http://www.111cn.net/database/mysql/53769.htm

需要注意:默認情況下,mysqldump並不會導出數據庫的存儲過程和函數,如果數據庫上創建了存儲過程且備份是需要備份存儲過程,那就需要用參數 -R 來指定,

例如:

 代碼如下 復制代碼

root@localhost bin]# mysqldump -uroot -p -hlocalhost -P3306 -n -d -t -R DBName > procedure_name.sql



http://www.linuxidc.com/Linux/2012-07/66140.htm

今天使用mysqldump導出數據庫,導入到新庫的時候,發現沒有存儲過程。

默認居然不是完整的啊。

加上“-R”,就好了。

-R, --routines      Dump stored routines (functions and procedures).

現在用:

mysqldump -uroot -ppassword -R dbname> dbname.sql

導入更方便:

mysql -uroot -ppassword dbname< dbname.sql

記得導入之前先建庫。

CREATE DATABASE dbname DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;

 

 

==================================================

 

http://blog.csdn.net/mchdba/article/details/12159239

-- 大表數據遷移,每天凌晨1點到5點執行,執行間隔時間10分鍾,遷移舊數據到歷史表。

DELIMITER $$

 

USE `dbx`$$

 

DROP PROCEDURE IF EXISTS `pro_xx`$$

 

CREATE  PROCEDURE `pro_xx`()

BEGIN  

   DECLARE p_oalid INT DEFAULT 0;

   DECLARE STOP INT DEFAULT 0; 

   

   DECLARE cur_oalid CURSOR FOR

         SELECToal.id FROM oal_xxx oal WHERE oal.`ymd` <CONCAT(YEAR(DATE_ADD(NOW(),INTERVAL -1 MONTH)),'-',MONTH(DATE_ADD(NOW(),INTERVAL -1 MONTH )),'-',DAY(DATE_ADD(NOW(),INTERVAL-1 MONTH ))) LIMIT 1000;  

   DECLARE EXIT HANDLER FOR SQLSTATE '02000'  /**包含游標not found*/

   BEGIN

        SET STOP=1;

         INSERTINTO db_logs(log_type,table_name,action_name,log_msg,create_time)

         SELECT1, 'oal_xxx','pro_oal_log_move',CONCAT('primary key:',p_oalid,' 游標執行正常結束!'),NOW();       

   END;

       

   DECLARE EXIT HANDLER FOR SQLEXCEPTION

   BEGIN

         SETSTOP=1;

         INSERTINTO db_logs(log_type,table_name,action_name,log_msg,create_time)

         SELECT2, 'oal_xxx','pro_oal_log_move',CONCAT('primary key:',p_oalid,' 移動執行失敗'),NOW();

   END; 

   

   OPEN cur_oalid;      

      

    -- 讀取一行數據到變量  

   FETCH cur_oalid INTO p_oalid;

 

     -- 這個就是判斷是否游標已經到達了最后  

   WHILE STOP <> 1 DO 

         -- select p_id;

         START TRANSACTION; 

     --   進行數據遷移

             REPLACE INTO oal_xxx_history SELECT oal.*FROM oal_xxx oal WHERE oal.id=p_oalid ;

             DELETE FROM oal_xxx WHERE id=p_oalid;

                          

             -- INSERT INTO t (tid) VALUES (p_tid);

         COMMIT;  

            

           

        -- 讀取下一行的數據   

       FETCH cur_oalid INTO p_oalid;

      END WHILE;         

   CLOSE cur_oalid; -- 關閉游標  

 END$$

 

DELIMITER ;

 

 

http://www.jb51.net/article/27068.htm

mysql 數據遷移用的一個存儲過程,需要的朋友可以收藏下。

代碼如下:


DELIMITER $$ 
USE `servant_591up`$$ 
DROP PROCEDURE IF EXISTS `sp_move_data`$$ 
CREATE PROCEDURE `sp_move_data`() 
BEGIN 
DECLARE v_exit INT DEFAULT 0; 
DECLARE v_spid BIGINT; 
DECLARE v_id BIGINT; 
DECLARE i INT DEFAULT 0; 
DECLARE c_table INT; 
DECLARE v_UniqueKey VARCHAR(57); 
DECLARE v_TagCatalogId INT; 
DECLARE v_RootCatalogId INT; 
DECLARE v_UserId BIGINT; 
DECLARE v_QuestionId CHAR(36); 
DECLARE v_CorrectCount INT; 
DECLARE v_ErrorCount INT; 
DECLARE v_LastIsCorrect INT; 
DECLARE v_LastAnswerXML TEXT CHARSET utf8; 
DECLARE v_TotalCostTime INT; 
DECLARE v_Reviews VARCHAR(200) CHARSET utf8; 
DECLARE v_AnswerResultCategory INT; 
DECLARE v_LastCostTime INT; 
DECLARE v_LastAnswerTime DATETIME; 
DECLARE v_IsPublic INT; 
DECLARE v_SUBJECT INT; 
DECLARE v_TotalCount INT; 
DECLARE v_AnswerMode SMALLINT(6); 
DECLARE v_ExerciseWeight FLOAT; 
DECLARE c_ids CURSOR FOR SELECT UniqueKey,TagCatalogId,RootCatalogId,UserId,QuestionId,CorrectCount,ErrorCount,LastIsCorrect,LastAnswerXML,TotalCostTime,Reviews,AnswerResultCategory,LastCostTime,LastAnswerTime,IsPublic,SUBJECT,TotalCount,AnswerMode,ExerciseWeight FROM ol_answerresult_56; 
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_exit=1; 
OPEN c_ids; 
REPEAT 
FETCH c_ids INTO v_UniqueKey,v_TagCatalogId,v_RootCatalogId,v_UserId,v_QuestionId,v_CorrectCount,v_ErrorCount,v_LastIsCorrect,v_LastAnswerXML,v_TotalCostTime,v_Reviews,v_AnswerResultCategory,v_LastCostTime,v_LastAnswerTime,v_IsPublic,v_SUBJECT,v_TotalCount,v_AnswerMode,v_ExerciseWeight; 
IF v_exit = 0 THEN 
SET @vv_id = v_id; 
SELECT MOD(v_UserId,100) INTO c_table; 
SET @SQL_CONTEXT = 
CONCAT('INSERT INTO new_answerresult_', 
c_table,' 
(UniqueKey,TagCatalogId,RootCatalogId,UserId,QuestionId,CorrectCount,ErrorCount,LastIsCorrect,LastAnswerXML,TotalCostTime,Reviews,AnswerResultCategory,LastCostTime,LastAnswerTime,IsPublic,SUBJECT,TotalCount,AnswerMode,ExerciseWeight)values(', 
'''',v_UniqueKey,'''',',', 
v_TagCatalogId,',', 
v_RootCatalogId,',', 
v_UserId,',', 
'''',v_QuestionId,'''',',', 
v_CorrectCount,',', 
v_ErrorCount,',', 
v_LastIsCorrect,',', 
'''',v_LastAnswerXML,'''',',', 
v_TotalCostTime,',', 
'''',REPLACE(IFNULL(v_Reviews,''),'''',''),'''',',', 
v_AnswerResultCategory,',', 
v_LastCostTime,',', 
'''',v_LastAnswerTime,'''',',', 
v_IsPublic,',', 
v_SUBJECT,',', 
v_TotalCount,',', 
v_AnswerMode,',', 
v_ExerciseWeight,')'); 
PREPARE STMT FROM @SQL_CONTEXT; 
EXECUTE STMT ; 
DEALLOCATE PREPARE STMT; 
END IF; 
SET i=i+1; 
#100 
#IF MOD(i,100)=0 THEN COMMIT; 
#END IF; 
UNTIL v_exit=1 
END REPEAT; 
CLOSE c_ids; 
#COMMIT; 
END$$ 
DELIMITER ; 
 
 
=================
http://blog.csdn.net/myron_sqh/article/details/13633239

存儲過程如同一門程序設計語言,同樣包含了數據類型、流程控制、輸入和輸出和它自己的函數庫。


--------------------基本語法--------------------

一.創建存儲過程
create procedure sp_name()
begin
.........
end

二.調用存儲過程
1.基本語法:call sp_name()
注意:存儲過程名稱后面必須加括號,哪怕該存儲過程沒有參數傳遞

三.刪除存儲過程
1.基本語法:
drop procedure sp_name//

2.注意事項
(1)不能在一個存儲過程中刪除另一個存儲過程,只能調用另一個存儲過程

四.其他常用命令

1.show procedure status
顯示數據庫中所有存儲的存儲過程基本信息,包括所屬數據庫,存儲過程名稱,創建時間等

2.show create procedure sp_name
顯示某一個mysql存儲過程的詳細信息


--------------------數據類型及運算符--------------------
一、基本數據類型:

二、變量:

自定義變量:DECLARE   a INT ; SET a=100;    可用以下語句代替:DECLARE a INT DEFAULT 100;

變量分為用戶變量系統變量,系統變量又分為會話和全局級變量

用戶變量:用戶變量名一般以@開頭,濫用用戶變量會導致程序難以理解及管理

1、 在mysql客戶端使用用戶變量
mysql> SELECT 'Hello World' into @x;
mysql> SELECT @x;

mysql> SET @y='Goodbye Cruel World';
mysql> select @y;

mysql> SET @z=1+2+3;
mysql> select @z;


2、 在存儲過程中使用用戶變量

mysql> CREATE PROCEDURE GreetWorld( ) SELECT CONCAT(@greeting,' World');
mysql> SET @greeting='Hello';
mysql> CALL GreetWorld( );


3、 在存儲過程間傳遞全局范圍的用戶變量
mysql> CREATE PROCEDURE p1( )   SET @last_procedure='p1';
mysql> CREATE PROCEDURE p2( ) SELECT CONCAT('Last procedure was ',@last_procedure);
mysql> CALL p1( );
mysql> CALL p2( );

 

三、運算符:
1.算術運算符
+     加   SET var1=2+2;       4
-     減   SET var2=3-2;       1
*      乘   SET var3=3*2;       6
/     除   SET var4=10/3;      3.3333
DIV   整除 SET var5=10 DIV 3; 3
%     取模 SET var6=10%3 ;     1

2.比較運算符
>            大於 1>2 False
<            小於 2<1 False
<=           小於等於 2<=2 True
>=           大於等於 3>=2 True
BETWEEN      在兩值之間 5 BETWEEN 1 AND 10 True
NOT BETWEEN 不在兩值之間 5 NOT BETWEEN 1 AND 10 False
IN           在集合中 5 IN (1,2,3,4) False
NOT IN       不在集合中 5 NOT IN (1,2,3,4) True
=             等於 2=3 False
<>, !=       不等於 2<>3 False
<=>          嚴格比較兩個NULL值是否相等 NULL<=>NULL True
LIKE          簡單模式匹配 "Guy Harrison" LIKE "Guy%" True
REGEXP       正則式匹配 "Guy Harrison" REGEXP "[Gg]reg" False
IS NULL      為空 0 IS NULL False
IS NOT NULL 不為空 0 IS NOT NULL True

3.邏輯運算符

4.位運算符
|   或
&   與
<< 左移位
>> 右移位
~   非(單目運算,按位取反)

注釋:

mysql存儲過程可使用兩種風格的注釋
雙橫杠:--

該風格一般用於單行注釋
c風格:/* 注釋內容 */ 一般用於多行注釋

--------------------流程控制--------------------
一、順序結構
二、分支結構

if
case

三、循環結構
for循環
while循環
loop循環
repeat until循環

注:
區塊定義,常用
begin
......
end;
也可以給區塊起別名,如:
lable:begin
...........
end lable;
可以用leave lable;跳出區塊,執行區塊以后的代碼

begin和end如同C語言中的{ 和 }。

--------------------輸入和輸出--------------------

mysql存儲過程的參數用在存儲過程的定義,共有三種參數類型,IN,OUT,INOUT
Create procedure|function([[IN |OUT |INOUT ] 參數名 數據類形...])

IN 輸入參數
表示該參數的值必須在調用存儲過程時指定,在存儲過程中修改該參數的值不能被返回,為默認值

OUT 輸出參數
該值可在存儲過程內部被改變,並可返回

INOUT 輸入輸出參數
調用時指定,並且可被改變和返回

IN參數例子:
CREATE PROCEDURE sp_demo_in_parameter(IN p_in INT)
BEGIN
SELECT p_in; --查詢輸入參數
SET p_in=2; --修改
select p_in;--查看修改后的值
END;

執行結果:
mysql> set @p_in=1
mysql> call sp_demo_in_parameter(@p_in)

mysql> select @p_in;

以上可以看出,p_in雖然在存儲過程中被修改,但並不影響@p_id的值

OUT參數例子
創建:
mysql> CREATE PROCEDURE sp_demo_out_parameter(OUT p_out INT)
BEGIN
SELECT p_out;/*查看輸出參數*/
SET p_out=2;/*修改參數值*/
SELECT p_out;/*看看有否變化*/
END;

執行結果:
mysql> SET @p_out=1
mysql> CALL sp_demo_out_parameter(@p_out)

mysql> SELECT @p_out;

INOUT參數例子:
mysql> CREATE PROCEDURE sp_demo_inout_parameter(INOUT p_inout INT)
BEGIN
SELECT p_inout;
SET p_inout=2;
SELECT p_inout;
END;

執行結果:
set @p_inout=1
call sp_demo_inout_parameter(@p_inout) //

select @p_inout;

 

 

附:函數庫
mysql存儲過程基本函數包括:字符串類型,數值類型,日期類型

一、字符串類
CHARSET(str) //返回字串字符集
CONCAT (string2 [,… ]) //連接字串
INSTR (string ,substring ) //返回substring首次在string中出現的位置,不存在返回0
LCASE (string2 ) //轉換成小寫
LEFT (string2 ,length ) //從string2中的左邊起取length個字符
LENGTH (string ) //string長度
LOAD_FILE (file_name ) //從文件讀取內容
LOCATE (substring , string [,start_position ] ) 同INSTR,但可指定開始位置
LPAD (string2 ,length ,pad ) //重復用pad加在string開頭,直到字串長度為length
LTRIM (string2 ) //去除前端空格
REPEAT (string2 ,count ) //重復count次
REPLACE (str ,search_str ,replace_str ) //在str中用replace_str替換search_str
RPAD (string2 ,length ,pad) //在str后用pad補充,直到長度為length
RTRIM (string2 ) //去除后端空格
STRCMP (string1 ,string2 ) //逐字符比較兩字串大小,
SUBSTRING (str , position [,length ]) //從str的position開始,取length個字符,
注:mysql中處理字符串時,默認第一個字符下標為1,即參數position必須大於等於1
mysql> select substring(’abcd’,0,2);
+———————–+
| substring(’abcd’,0,2) |
+———————–+
|                       |
+———————–+
1 row in set (0.00 sec)

mysql> select substring(’abcd’,1,2);
+———————–+
| substring(’abcd’,1,2) |
+———————–+
| ab                    |
+———————–+
1 row in set (0.02 sec)

TRIM([[BOTH|LEADING|TRAILING] [padding] FROM]string2) //去除指定位置的指定字符
UCASE (string2 ) //轉換成大寫
RIGHT(string2,length) //取string2最后length個字符
SPACE(count) //生成count個空格

二、數值類型

ABS (number2 ) //絕對值
BIN (decimal_number ) //十進制轉二進制
CEILING (number2 ) //向上取整
CONV(number2,from_base,to_base) //進制轉換
FLOOR (number2 ) //向下取整
FORMAT (number,decimal_places ) //保留小數位數
HEX (DecimalNumber ) //轉十六進制
注:HEX()中可傳入字符串,則返回其ASC-11碼,如HEX(’DEF’)返回4142143
也可以傳入十進制整數,返回其十六進制編碼,如HEX(25)返回19
LEAST (number , number2 [,..]) //求最小值
MOD (numerator ,denominator ) //求余
POWER (number ,power ) //求指數
RAND([seed]) //隨機數
ROUND (number [,decimals ]) //四舍五入,decimals為小數位數]

注:返回類型並非均為整數,如:

(1)默認變為整形值
mysql> select round(1.23);
+————-+
| round(1.23) |
+————-+
|           1 |
+————-+
1 row in set (0.00 sec)

mysql> select round(1.56);
+————-+
| round(1.56) |
+————-+
|           2 |
+————-+
1 row in set (0.00 sec)

(2)可以設定小數位數,返回浮點型數據

mysql> select round(1.567,2);
+—————-+
| round(1.567,2) |
+—————-+
|           1.57 |
+—————-+
1 row in set (0.00 sec)

SIGN (number2 ) //返回符號,正負或0
SQRT(number2) //開平方

三、日期類型

ADDTIME (date2 ,time_interval ) //將time_interval加到date2
CONVERT_TZ (datetime2 ,fromTZ ,toTZ ) //轉換時區
CURRENT_DATE ( ) //當前日期
CURRENT_TIME ( ) //當前時間
CURRENT_TIMESTAMP ( ) //當前時間戳
DATE (datetime ) //返回datetime的日期部分
DATE_ADD (date2 , INTERVAL d_value d_type ) //在date2中加上日期或時間
DATE_FORMAT (datetime ,FormatCodes ) //使用formatcodes格式顯示datetime
DATE_SUB (date2 , INTERVAL d_value d_type ) //在date2上減去一個時間
DATEDIFF (date1 ,date2 ) //兩個日期差
DAY (date ) //返回日期的天
DAYNAME (date ) //英文星期
DAYOFWEEK (date ) //星期(1-7) ,1為星期天
DAYOFYEAR (date ) //一年中的第幾天
EXTRACT (interval_name FROM date ) //從date中提取日期的指定部分
MAKEDATE (year ,day ) //給出年及年中的第幾天,生成日期串
MAKETIME (hour ,minute ,second ) //生成時間串
MONTHNAME (date ) //英文月份名
NOW ( ) //當前時間
SEC_TO_TIME (seconds ) //秒數轉成時間
STR_TO_DATE (string ,format ) //字串轉成時間,以format格式顯示
TIMEDIFF (datetime1 ,datetime2 ) //兩個時間差
TIME_TO_SEC (time ) //時間轉秒數]
WEEK (date_time [,start_of_week ]) //第幾周
YEAR (datetime ) //年份
DAYOFMONTH(datetime) //月的第幾天
HOUR(datetime) //小時
LAST_DAY(date) //date的月的最后日期
MICROSECOND(datetime) //微秒
MONTH(datetime) //月
MINUTE(datetime) //分

注:可用在INTERVAL中的類型:DAY ,DAY_HOUR ,DAY_MINUTE ,DAY_SECOND ,HOUR ,HOUR_MINUTE ,HOUR_SECOND ,MINUTE ,MINUTE_SECOND,MONTH ,SECOND ,YEAR
DECLARE variable_name [,variable_name...] datatype [DEFAULT value]; 
其中,datatype為mysql的數據類型,如:INT, FLOAT, DATE, VARCHAR(length)

例:

DECLARE l_int INT unsigned default 4000000; 
DECLARE l_numeric NUMERIC(8,2) DEFAULT 9.95; 
DECLARE l_date DATE DEFAULT '1999-12-31'; 
DECLARE l_datetime DATETIME DEFAULT '1999-12-31 23:59:59';
DECLARE l_varchar VARCHAR(255) DEFAULT 'This will not be padded';

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM