MySQL - 存儲過程

一、概述

  存儲過程可以理解為一段 SQL 語句的集合(相當于 PHP 中的一個函數方法,去實現業務邏輯),它們被事先編譯好并且存儲在數據庫中。

  調用存儲過程與直接執行 SQL 語句的效果是相同的,但是存儲過程的一個好處是處理邏輯都封裝在數據庫端。

  當我們調用存儲過程的時候,我們不需要了解其中的處理邏輯,一旦處理邏輯發生變化,只需要修改存儲過程即可,對調用它的程 序完全無影響。

  調用存儲過程和函數可以簡化應用開發人員的很多工作,減少數據在數據庫和應用服務器之間的傳輸,減少了和腳本語言的交互以及帶寬,可以提高數據處理的效率。

 
二、存儲過程結構

?

create procedure 【存儲過程名(參數列表)】
begin【存儲過程體】
end

?

call 存儲過程名(參數列表)


?

 
三、使用示例

 
實例1、新建一張數據表,并向這張數據表中添加 100 萬條記錄。

(1)新建數據表

CREATE TABLE `test_table` (`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`loop` int(10) unsigned NOT NULL DEFAULT '0',`name` varchar(256) NOT NULL DEFAULT '',`pen_name` varchar(256) NOT NULL DEFAULT '',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


(2)新建存儲過程

DROP PROCEDURE IF EXISTS insert_many_rows;CREATE PROCEDURE insert_many_rows (IN loopTime INT)
BEGINDECLARE executedTime INT ;SET executedTime = loopTime;while executedTime > 0 DOINSERT INTO test_table(NULL, 0, 'sss', 'kkk');SET executedTime = executedTime - 1;END WHILE;
END;


(3)呼叫存儲過程

CALL insert_many_rows(1000000);

結果應該是新建的數據表中已經有了 100 萬條記錄。

 
實例2:通過存儲過程創建10個數據表,分別為test_table_0 ~ test_table_9

(1)創建存儲過程

DROP PROCEDURE IF EXISTS create_test_tables;
CREATE PROCEDURE `create_test_tables`()
BEGINDECLARE i INT;DECLARE tableName VARCHAR(30);DECLARE sqlText text;SET i = 0;WHILE i < 10 DOSET tableName = CONCAT('test_table_' , i);SET sqlText = CONCAT('CREATE TABLE ', tableName , '(`id` int(10) unsigned NOT NULL AUTO_INCREMENT,`loop` int(10) unsigned NOT NULL DEFAULT ''0'',`name` varchar(256) NOT NULL DEFAULT '''',`pen_name` varchar(256) NOT NULL DEFAULT '''',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2001001 DEFAULT CHARSET=utf8;');SET @sqlText = sqlText;PREPARE stmtFROM@sqlText;EXECUTE stmt;DEALLOCATE PREPARE stmt;SET i = i + 1;END WHILE;
END


(2)呼叫存儲過程

CALL create_test_tables();


 
?四、分析

 
1、存儲過程的參數類型:

(1)IN 表示只是用來輸入。

(2)OUT 表示只是用來輸出。

(3)INOUT 可以用來輸入,也可以用作輸出。

 
2、存儲過程中的變量聲明

通過 DECLARE 來聲明一個局部變量,該變量的作用域只是 begin....end 塊中。

變量的聲明可以添加默認值,比如:

DECLARE executedTime INT DEFAULT 0;

 
3、流程控制語句語法

if 的語法格式為:
if 條件表達式 then 語句[elseif 條件表達式 then 語句] ....[else 語句]
end ifcase 的語法格式
首先是第一種寫法:
case 表達式when 值 then 語句when 值 then 語句...[else 語句]
end case
然后是第二種寫法:
casewhen 表達式 then 語句when 表達式 then 語句....[else 語句]
end caseloop 循環 語法格式為:
[標號:] loop循環語句
end loop [標號]while 語法
while a>100 do循環語句
End whileRepeat ? ? ? ?//游標SQL語句1UNTIL 條件表達式
END Repeat;LoopSQL語句所有的條件判斷和跳出需要自己實現
End loopleave 語句用來從標注的流程構造中退出,它通常和 begin...end 或循環一起使用
leave 標號;聲明語句結束符,可以自定義:
DELIMITER [符合]
delimiter $$

 
4、存儲過程中的數據類型

數值類型:Int、float、double、decimal

日期類型:timestamp、date、year

字符串:char、varchar、text


五、存儲過程優缺點

 
1、優點:

(1)執行速度快。因為我們的每個 SQL 語句都需要經過編譯,然后再運行。但是存儲過程都是直接編譯好了之后,直接運行即可。

(2)減少網絡流量,我們傳輸一個存儲過程比我們傳輸大量的 SQL 語句的開銷要小得多。

(3)提高系統安全性,因為存儲過程可以使用權限控制,而且參數化的存儲過程可以有效地防止 SQL 注入攻擊。保證了其安全性。

(4)耦合性降低。當我們的表結構發生了調整或變動之后,我們可以修改相應的存儲過程,我們的應用程序在一定程度上需要改動的地方就較小了。

(5)重用性強,因為我們寫好一個存儲過程之后,再次調用它只需要一個名稱即可,也就是”一次編寫,隨處調用”,而且使用存儲過程也可以讓程序的模塊化加強。

 
2、缺點:

(1)可移植性差。因為存儲過程是和數據庫綁定的,如果我們要更換數據庫之類的操作,可能很多地方都需要改動。

(2)修改不方便。因為對于存儲過程而言,我們并不能特別有效的調試,它的一些 bug 可能發現的更晚一些,增加了應用的危險性。

(3)優勢不明顯和贅余功能。對于小型 web 應用來說,如果我們使用語句緩存,發現編譯 SQL 的開銷并不大,但是使用存儲過程卻需要檢查權限一類的開銷,這些贅余功能也會在一定程度上拖累性能。

 
六、PHP 中使用存儲過程

PHP 中也是可以使用存儲過程的,存儲過程的使用也很簡單。只要將存儲過程的創建語句和call語句分別執行就可以了。

這里使用最簡單的 pdo 調用方式,如果在框架中,為了保持代碼的美觀,請使用框架自帶的查詢執行語句。```
?

<?php
declare(strict_types = 1);// 注意:創建存儲過程和call存儲過程要分開執行,創建存儲過程之后,將創建存儲過程部分注釋掉,然后打開call存儲過程代碼執行// 連接 pdo
$dsn = "mysql:dbname=test;host=127.0.0.1";
$pdo = new PDO($dsn,'root','123456');# ------------------------------- 創建存儲過程 --------------------------
// 創建存儲過程語句賦值到變量
$sql = 'DROP PROCEDURE IF EXISTS insert_many_rows_2;
CREATE PROCEDURE insert_many_rows_2 (IN loopTime INT)
BEGINDECLARE executedTime INT ;SET executedTime = loopTime;while executedTime > 0 DOINSERT INTO test_table(NULL, 0, \'sss\', \'kkk\');SET executedTime = executedTime - 1;END WHILE;
END;';// 執行
$stmt = $pdo->query($sql);
var_dump($stmt->fetchAll(2));#---------------------- call 存儲過程 --------------------------/*$callSql = 'CALL insert_many_rows(1000000);';
$stmt = $pdo->query($callSql);
var_dump($stmt->fetchAll(2));*/

?

七、總結

存儲過程只做了解即可,事實上很多公司都是禁止使用存儲過程的,主要是因為一旦使用存儲過程,新人接手將會非常困難,并且難以調試和擴展,而且沒有可移植性。

何況存儲過程能夠解決的問題,一般程序代碼也是可以解決的,因此在非必要情況下,還是使用代碼去實現,而不是考慮去用存儲過程。

?

原文鏈接:https://www.haveyb.com/article/61

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/282125.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/282125.shtml
英文地址,請注明出處:http://en.pswp.cn/news/282125.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

白話聊應用架構

產業互聯網時代&#xff0c;數字化轉型&#xff08;數字化演化歷史&#xff09;已成為一種趨勢&#xff0c;各行各業都投入到數字化轉型的浪潮中來。節后有個客戶項目參與者問我架構方面的事情&#xff0c;我想來想去對于非IT人來說&#xff0c;可能應用架構是最容易理解&#…

python大數_python處理大數字的方法

本文實例講述了python處理大數字的方法。分享給大家供大家參考。具體實現方法如下&#xff1a;def getFactorial(n):"""returns the factorial of n"""if n 0:return 1else:k n * getFactorial(n-1)return kfor k in range(1, 70):print "…

數據庫分庫分表、讀寫分離的原理和實現,以及使用場景

2019獨角獸企業重金招聘Python工程師標準>>> 為什么要分庫分表和讀寫分離&#xff1f; 類似淘寶網這樣的網站&#xff0c;海量數據的存儲和訪問成為了系統設計的瓶頸問題&#xff0c;日益增長的業務數據&#xff0c;無疑對數據庫造成了相當大的負載&#xff0c;同時…

談談一些有趣的CSS題目(十六)-- 奇妙的 background-clip: text

開本系列&#xff0c;談談一些有趣的 CSS 題目&#xff0c;題目類型天馬行空&#xff0c;想到什么說什么&#xff0c;不僅為了拓寬一下解決問題的思路&#xff0c;更涉及一些容易忽視的 CSS 細節。 解題不考慮兼容性&#xff0c;題目天馬行空&#xff0c;想到什么說什么&#x…

第五周軟件工程作業-每周例行報告

一、PSP T名稱C內容ST開始時間ED結束時間中斷時間/min實際時間/minScrum會議第一次Scrum會議10月13日11:3010月13日12:10040第二次Scrum會議10月14日15:3010月14日15:55025第三次Scrum會議10月15日13:3010月15日14:05035第四次Scrum會議10月16日11:3010月16日13:00090第五次Scr…

MySQL - 觸發器

一、概述 Mysql 允許通過觸發器、存儲過程、函數的形式來存儲代碼。 觸發器可以讓你在執行 Insert、Update、Delete的時候&#xff0c;執行一些特定的操作。可以在Mysql中指定是在Sql語句執行之前觸發還是執行后觸發。 二、使用觸發器需要注意的點 對每一個表的每一個事件&a…

Docker Desktop 可以直接啟用Kubernetes 1.25 了

作為目前事實上的容器編排系統標準&#xff0c;K8s 無疑是現代云原生應用的基石&#xff0c;很多同學入門可能直接就被卡到第一關&#xff0c;從哪去弄個 K8s 的環境&#xff0c; Docker Desktop 自帶了Kubernetes 服務&#xff0c;但是在過往的經驗中就是用梯子也安裝不了&…

截取url的host_java正則表達式獲取url的host示例

java正則表達式獲取url的host示例 復制代碼 代碼如下: public static String getHost(String url){if(url==null||url.trim().equals("")){return ""; } String host = ""; Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+&qu…

MySQL - 視圖

一、概述 Mysql 5.0 版本后開始引入視圖。視圖本身是一個虛擬表&#xff0c;不存放任何數據。在使用 sql 語句訪問視圖的時候&#xff0c;他返回的數據都是在查詢過程中從其他表動態生成的。 二、使用視圖   1、創建視圖 CREATE VIEW comic_view as SELECT comic_id,name,pe…

Linux環境下壓縮與解壓命令大全

tar命令 解包&#xff1a;tar zxvf FileName.tar 打包&#xff1a;tar czvf FileName.tar DirName gz命令 解壓1&#xff1a;gunzip FileName.gz 解壓2&#xff1a;gzip -d FileName.gz 壓縮&#xff1a;gzip FileName .tar.gz 和 .tgz 解壓&#xff1a;tar zxvf FileName.tar.…

Centos 磁盤管理及配額管理

實驗內容&#xff1a;一.添加兩塊硬盤&#xff0c;使用LVM做成VG01組&#xff0c;在該VG中新建兩個LV。二.將這兩個LV格式化為ext4/xfs&#xff0c;開機自動掛載到系統mnt1,mnt2目錄下。三.lv02開啟磁盤配額功能&#xff0c;用來進行用戶與組分配額的實驗。四.在系統里添加用戶…

OnionArch - 采用DDD+CQRS+.Net 7.0實現的洋蔥架構

博主最近失業在家&#xff0c;找工作之余&#xff0c;看了一些關于洋蔥&#xff08;整潔&#xff09;架構的資料和項目&#xff0c;有感而發&#xff0c;自己動手寫了個洋蔥架構解決方案&#xff0c;起名叫OnionArch。基于最新的.Net 7.0 RC1, 數據庫采用PostgreSQL, 目前實現了…

spark寫出分布式的訓練算法_利用 Spark 和 scikit-learn 將你的模型訓練加快 100 倍...

在 Ibotta&#xff0c;我們訓練了許多機器學習模型。這些模型為我們的推薦系統、搜索引擎、定價優化引擎、數據質量等提供動力。它們在與我們的移動應用程序交互時為數百萬用戶做出預測。當我們使用 Spark 進行數據處理時&#xff0c;我們首選的機器學習框架是 scikit-learn。隨…

理解LinkedHashMap

1. LinkedHashMap概述&#xff1a;LinkedHashMap是HashMap的一個子類&#xff0c;它保留插入的順序&#xff0c;如果需要輸出的順序和輸入時的相同&#xff0c;那么就選用LinkedHashMap。LinkedHashMap是Map接口的哈希表和鏈接列表實現&#xff0c;具有可預知的迭代順序。此實現…

MySQL - 鎖

一、什么是鎖 鎖是數據庫系統區別于文件系統的一個關鍵特性。鎖機制用于管理對共享資源的并發訪問。 二、MySQL 不同存儲引擎支持的鎖機制 存儲引擎支持的鎖類型Myisam表鎖Innodb行鎖、表鎖Memory表鎖BDB頁鎖、表鎖表鎖&#xff1a;直接鎖住的是一個表&#xff0c;開銷小&…

數據庫時區那些事兒 - MySQL的時區處理

原文地址 當JVM時區和數據庫時區不一致的時候&#xff0c;會發生什么&#xff1f;這個問題也許你從來沒有注意過&#xff0c;但是當把Java程序容器化的時候&#xff0c;問題就浮現出來了&#xff0c;因為目前幾乎所有的Docker Image的時區都是UTC。本文探究了MySQL及其JDBC驅動…

java_函數的重載

函數的重載&#xff08;Overload&#xff09;概念&#xff1a;在同一個類中&#xff0c;允許存在一個以上的同名函數&#xff0c;只要他們的參數個數或者參數類型不同即可。函數功能一樣&#xff0c;僅僅是參與運算的未知內同不同時&#xff0c;可以定義多函數&#xff0c;卻使…

全新升級的AOP框架Dora.Interception[2]: 基于約定的攔截器定義方式

Dora.Interception&#xff08;github地址&#xff0c;覺得不錯不妨給一顆星&#xff09;有別于其他AOP框架的最大的一個特點就是采用針對“約定”的攔截器定義方式。如果我們為攔截器定義了一個接口或者基類&#xff0c;那么攔截方法將失去任意注冊依賴服務的靈活性。除此之外…

redis watch使用場景_redis不得不會的事務玩法

我們都知道redis追求的是簡單&#xff0c;快速&#xff0c;高效&#xff0c;在這種情況下也就拒絕了支持window平臺&#xff0c;學sqlserver的時候&#xff0c;我們知道事務還算是個比較復雜的東西&#xff0c;所以這吊毛要是照搬到redis中去&#xff0c;理所當然redis就不是那…

加快Android Studio的編譯速度

從Eclipse切換到Android Studio后&#xff0c;感覺Android Studio的build速度比Eclipse慢很多&#xff0c;以下幾個方法可以提高Android Studio的編譯速度使用Gradle 2.4Gradle 2.4對執行性能有很大的優化&#xff0c;但Android Studio現在默認使用的是Gradle 2.2,所以我們需要…