mysql數據遷移之<存儲過程>

背景:sql

    要求從數據庫

balance_0x123145d67520b4h63B9D60d7C1435bffF41aFa25  這個表沒有goods_id

導出數據到函數

balance_25  這個表多了一個 goods_id 字段,同時還要把這個goods_id 存進去(就是上面的表名後綴,也就是goods表的id)

將表名後綴取後兩位,把全部後綴相同的表數據合併到一張表,並且不能肯定這種表有多少個,只能選擇寫個過程來處理了,資源

這種表名後綴是由goods表的id產生的,有多少個id就有多少這種表,因此下面這條sql查出來是一個集合string

SELECT `id` FROM goods WHERE `name` IS NOT NULL;

正文:變量

    既然說到過程和函數,就要看一下它們的區別以及我爲何要選擇過程來處理而不是函數;date

1. 存儲函數有且只有一個返回值,而存儲過程不能有返回值。
2. 函數只能有輸入參數,並且不能帶in, 而存儲過程能夠有多個in,out,inout參數。
3. 存儲過程當中的語句功能更強大,存儲過程能夠實現很複雜的業務邏輯,而函數有不少限制,如不能在函數中使用insert,update,delete,create等語句;存儲函數只完成查詢的工做,可接受輸入參數並返回一個結果,也就是函數實現的功能針對性比較強。
4. 存儲過程能夠調用存儲函數。但函數不能調用存儲過程。
5. 存儲過程通常是做爲一個獨立的部分來執行(call調用)。而函數能夠做爲查詢語句的一個部分來調用.

那麼到了個人需求:select

1. 我不須要返回值;
2. 不須要傳遞參數;
3. 我須要執行insert、select等sql

這樣只能選擇寫一個過程(雖然很麻煩,but I like)循環

#以root用戶建立一個名稱爲`PROCEDURE_BALANCE`的存儲過程
CREATE DEFINER=`root`@`%` PROCEDURE `PROCEDURE_BALANCE`()
BEGIN
    #定義判斷變量
    DECLARE flag varchar(50);
    #定義名爲goods_id的遊標(查詢goods表name不爲空的全部id,賦值給goods_id)
    DECLARE goods_id CURSOR FOR SELECT `id` FROM goods WHERE `name` IS NOT NULL;
    #循環賦初始值
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET flag=NULL;
    #打開遊標
    OPEN goods_id;
    #遊標讀取下一行
    FETCH goods_id INTO flag;
    #定義循環
    WHILE (flag is not null ) DO
        #sql拼接,替換相關變量 PS: 拼接表名這種能夠用'',可是拼接WHERE條件這種,好比 id='11',就須要三個''這種單引號,這裏細心想一下就能夠理解
        SET @string_sql = CONCAT('INSERT INTO userbalance_',RIGHT (flag, 2),'(SELECT id,''',flag,''',userAddress,amount,freezeAccount,createdAt,updatedAt,deletedAt FROM userbalance_',flag,')');
        #這個是打印每條sql,能夠不要
        SELECT @string_sql;
        #建立預處理語句
        PREPARE st FROM @string_sql;
        #執行這個sql
        EXECUTE st;
        #釋放預處理語句,(若是不釋放,在存儲過程結束以後,該預處理語句仍然會有效,佔用數據庫資源)
        DEALLOCATE PREPARE st;
        #賦值下一個遊標
        FETCH goods_id INTO flag;
    END WHILE;
    #關閉遊標, PS:用完後必須關閉,並且必須在循環外關閉
    CLOSE goods_id;
END
#PS:遊標必須在定義處理程序以前被定義,但變量必須在定義遊標以前被定義,順序就是變量定義-遊標定義-處理程序.
相關文章
相關標籤/搜索