Mysql - 游標/動態sql/事務

来源:http://www.cnblogs.com/elvinle/archive/2016/12/28/6229407.html
-Advertisement-
Play Games

游標這個在我目前的項目裡面用的還不多, 但是其功能還是很強大的. 動態sql以前都沒用過, 是跟著富士康(不是張全蛋的富土康哦)過來的同事學的. 還是挺好用的. 我的資料庫方面, 跟他學了不少. 在此, 感謝他一下, 建華鍋鍋. 事務在前面的篇章中其實已經出現過了, 這個東西好像還是程式中用的比較多 ...


游標這個在我目前的項目裡面用的還不多, 但是其功能還是很強大的.

動態sql以前都沒用過, 是跟著富士康(不是張全蛋的富土康哦)過來的同事學的. 還是挺好用的. 我的資料庫方面, 跟他學了不少. 在此, 感謝他一下, 建華鍋鍋.

事務在前面的篇章中其實已經出現過了, 這個東西好像還是程式中用的比較多一點.

由於之前的工作中碰到過一個場景, 正好將游標,動態sql,事務都用上了, 那麼我也弄一個例子好了, 想了一個別的場景, 與工作的那個場景不相干, 並沒有泄露公司業務機密之類的啊. 

先看例子吧, 然後在後面, 我補上語法.

一、例子

1. 建表

  既然是講例子, 當然不能忘記建表嘛, 從0開始. 

create table Goods
(
    Id int not null PRIMARY key auto_increment,
    Code varchar(50) comment '編碼',
    Name varchar(20) comment '名稱',
    Count int comment '數量',
    Brand varchar(20) comment '品牌'
) default charset=utf8 comment '商品表';

create table GoodDetails
(
    Id int not null PRIMARY key auto_increment,
    GId int not null comment 'Goods表Id',
   Name varchar(20) comment '名稱', Code varchar(
50) comment '編碼明細', Remark varchar(100) comment '備註' ) default charset=utf8 comment '商品明細';

 

2. 加入基礎數據

 

3. 虛擬場景介紹

公司最近進了一批物品, 就是上面的Goods表了, 並且準備給每一個物品進行編碼(編碼規則就是用Goods表的Code加上流水號, 去生成), 並打上條形碼.

這裡的功能就是生成商品明細和流水號的問題了, 一鍵生成. 這裡通常的實現方式有兩種:

方式一 : 程式生成

  在程式中, 讀取需要生成的數據, 比如上面這四條, 然後迴圈每一條, 給數據加上編碼, 總共生成出12條數據, 在吧這12條數據, 存入明細表中. 在數據量少的時候還好, 完全可以接受, 但是如果數據量多了, 那速度, 慢的讓人有砸電腦的衝動. Goods表的幾條數據, 到GoodDetails表中, 會變成數百, 甚至上千, 上萬. 

方式二 : 資料庫生成

  如果不想讀取出來再插入, 並且邏輯處理並不多,不複雜的情況下, 可以使用資料庫去生成. 還是很方便的, 速度也提升非常多.

那這裡, 我只介紹方式二了, 方式一, 只是處理麻煩一點.

 

4. 腳本:

delimiter $
drop PROCEDURE if EXISTS p_autocreate;
CREATE  PROCEDURE `p_autocreate`(IN g_ids VARCHAR(1000), IN nolength INT)
BEGIN
 DECLARE res_code INT;

 DECLARE res_msg VARCHAR (50);

 /*臨時表的條數*/
 DECLARE t_count INT;

 /**游標內使用變數**begin**/
 DECLARE g_id INT;

 DECLARE g_code VARCHAR (50);

 DECLARE d_code VARCHAR (50);

 DECLARE g_count INT (11);

 DECLARE g_name VARCHAR (20);
 /**游標內使用變數**end**/

 /**游標的位置**/
 DECLARE v_index INT DEFAULT 1;

 DECLARE done BIT DEFAULT 0;

 /*聲明游標*/
 DECLARE g_cursor CURSOR FOR SELECT id, CODE, NAME, COUNT FROM temp_goods;

 /*游標查詢時, 如果找不到下一個了, 會將done置為1*/
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

 /**創建臨時表**begin**/
 DROP TABLE IF EXISTS temp_goods;
 CREATE TEMPORARY TABLE temp_goods (
  Id INT NOT NULL, --  PRIMARY key auto_increment,
  CODE VARCHAR (50),
  NAME VARCHAR (20),
  COUNT INT
 ) DEFAULT CHARSET = utf8;
 /**創建臨時表**end**/

 /**初始化返回值**begin**/
 SET res_code := "-99";

 SET res_msg := "OK";
 /**初始化返回值**end**/

 IF (g_ids IS NOT NULL OR LENGTH(g_ids) > 0) THEN
SET @v_sql := CONCAT("INSERT INTO temp_goods(Id,Code,Name,Count) ", " select Id,Code,Name,Count from Goods ", " where ", " find_in_set(id, ", CHAR(34), g_ids, CHAR(34), ")>0 ;"); /*預編譯此動態sql, 並存入stmt中*/ PREPARE stmt FROM @v_sql; /*執行此動態sql, 此動態sql的作用, 是從Goods中提取有效數據*/ EXECUTE stmt; /*釋放此資源*/ DEALLOCATE PREPARE stmt; SELECT COUNT(1) INTO t_count FROM temp_goods; START TRANSACTION; -- 開始事務 IF (t_count > 0) THEN /*打開游標*/ OPEN g_cursor; REPEAT /*這裡的順序要與之前的順序保持一致*/ FETCH g_cursor INTO g_id, g_code, g_name, g_count; IF NOT done THEN SET v_index := 1; IF (IFNULL(g_count, 0) > 0) THEN WHILE (v_index <= g_count) DO SET d_code := CONCAT(g_code, LPAD(v_index, nolength, "0")); INSERT INTO GoodDetails(GId, NAME, CODE) VALUES (g_id, g_name, d_code); SET v_index := v_index + 1; END WHILE; END IF; END IF; UNTIL done END REPEAT; -- 結束repeat迴圈 CLOSE g_cursor; /*關閉游標*/ COMMIT; -- 提交事務 ELSE ROLLBACK; -- 回滾事務 SET res_code := "10"; SET res_msg := "系統中不存在相關記錄."; END IF; ELSE SET res_code := "5"; SET res_msg := "請選擇要生成的記錄"; END IF; DROP TABLE IF EXISTS temp_goods; SELECT res_msg; END $ delimiter ;

 

5. 結果:

 執行這個存儲過程

call p_autocreate('1,2,3,4', 3);

ok, 執行成功, 接下來, 來看一下GoodDetails表的數據:

我這裡的例子, 已經是最簡單的一個例子了, 在實際使用過程中, 可能比這個還要複雜一些, 數據更多一些.

 不過說到這個數據量, 我倒不介意, 多做一個實驗.

 

6. 實驗

  我將各自的數據量, 都修改為 10000, 如下圖, 這個時候, 要生成 40000 條數據, 並且插入到表中去. 如果使用程式處理插入資料庫的方式, 確實會慢一些.

  

資料庫的方式, 確實會快很多. 如下圖, 生成4w條數據, 然後插入GoodDetails表中, 花了不到4s的時間. 算是一個比較快的時間了.

  

OK, 接下來, 就來介紹一下他們的語法.

 

 二、游標

1. 語法

1.1 聲明游標

  declare 游標名 cursor for select 列名 from 表

1.2 打開游標

  open 游標名

1.3 游標前進

  fetch 游標名 into 變數a, 變數b ... 

1.4 關閉游標

  close 游標名

2. 註

  既然游標執行的方式, 像是一個迴圈, 那麼什麼時候才知道這個迴圈要結束呢.

  例子裡面, 有一句話,  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; 這句話的意思, 其實就是當游標找不到下一條數據的時候, 就回將變數 done 修改為1. 

  

三、動態sql

1. 語法

1.1 準備sql變數

  此sql變數必須是字元串格式的哦. 這樣可以動態生成需要執行的sql.

1.2 預編譯

  PREPARE stmt FROM @v_sql;

  這裡的stmt是一個變數, 名稱自己取

1.3 執行

  EXECUTE stmt;

1.4 釋放資源

  DEALLOCATE PREPARE stmt;

 

四、事務

1. 語法

到這裡, 我突然不知道說些什麼了. 那就簡單介紹下吧

1.1 開始事務

  start transation;

1.2 提交事務

  commit;

1.3 回滾事務

  rollback;


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • iOS開發小技巧 - 中文排序NSString 與 UnicodeObjective-C 中文 按拼音全排序 ...
  • 一、實現思路 1、在build.gradle中添加依賴,例如: 也可以將support-v4替換為appcompat-v7,例如: 因為appcompat-v7是依賴於support-v4的。 更多說明可參考官方文檔support library部分。 2、在xml中添加TabLayout和View ...
  •   任何一款直播軟體都必須進行美顏,不然哪來的那麼多美女,所以技術改變世界,不只是說說而已。美顏在採集的時候就得就行,讓主播實時看到直播的效果。 1.美顏原理   其實美顏的本質就是美白和磨皮,分別通過提高亮度和模糊像素點進行。我們一般用GPUImage這個開 ...
  • 一資料庫伺服器(SQL Server 2014)上的一個作業執行報錯,具體錯誤信息如下: Executed as user: NT SERVICE\SQLSERVERAGENT. 用戶 'xxxx\xxxxx$' 登錄失敗。 [SQLSTATE 28000] (Error 18456). The s... ...
  • 事務 事務是一種機制、是一種操作序列,它包含了一組資料庫操作命令,這組命令要麼全部執行,要麼全部不執行。 在資料庫系統上執行併發操作時事務是作為最小的控制單元來使用的。這特別適用於多用戶同時操作的數據通信系統。例如:訂票、銀行、保險公司以及證券交易系統等。 如果某一事務成功,則在該事務中進行的所有數 ...
  • 原文地址:http://blog.csdn.net/shmiloy001/article/details/6287317 首先,授權給指定用戶。 一個用戶的預設表空間只能有一個,但是你可以試下用下麵的語句為其授權在別的表空間中創建對像: alter user username quota unlim... ...
  • 在redis的官網上洋洋灑灑的大概提供了200多個命令,貌似看起來很多,但是這些都是別人預先給你定義好的,但你卻不能按照自己的意圖進行定製, 所以是不是感覺自己還是有一種被束縛的感覺,有這個感覺就對了。。。 一:Lua腳本 說來也巧,redis的大老闆給了你解決這種問題的方法,那就是Lua腳本,而且 ...
  • 1. 在ORACLE官網下載Oracle SQL Developer第三方資料庫驅動 下載頁面:http://www.oracle.com/technetwork/developer-tools/sql-developer/thirdparty-095608.html Download the My ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...