SQL進階知識:五、存儲過程和函數

今天介紹下關于存儲過程和函數的詳細介紹,并結合MySQL數據庫提供實際例子。

在MySQL中,存儲過程(Stored Procedures)和函數(Functions)是數據庫編程的重要組成部分,它們可以封裝SQL語句,提高代碼的復用性和安全性,同時減少網絡傳輸。以下是關于存儲過程和函數的詳細介紹,以及基于MySQL的實際例子。


一、存儲過程(Stored Procedures)

1. 存儲過程的基本概念

存儲過程是一組SQL語句的集合,封裝在一個名稱下,可以帶參數調用。存儲過程可以包含復雜的邏輯,支持條件語句、循環語句和變量聲明。

2. 存儲過程的優點

  • 代碼復用:存儲過程可以被多次調用,避免重復編寫SQL語句。
  • 性能提升:存儲過程在服務器端執行,減少了網絡傳輸。
  • 安全性:通過存儲過程可以限制用戶直接訪問表,提高數據的安全性。
  • 事務管理:存儲過程可以包含事務控制語句,確保操作的原子性。

3. 創建存儲過程

語法:

CREATE PROCEDURE procedure_name (IN|OUT|INOUT param1 type, ...)
BEGIN-- SQL語句
END;
  • IN參數:輸入參數,用于傳遞值到存儲過程。
  • OUT參數:輸出參數,用于返回值。
  • INOUT參數:既可以輸入也可以輸出。

4. 調用存儲過程

CALL procedure_name(param1, param2, ...);

5. 刪除存儲過程

DROP PROCEDURE procedure_name;

二、函數(Functions)

1. 函數的基本概念

函數是一組SQL語句的集合,封裝在一個名稱下,可以帶參數調用,并返回一個值。函數通常用于計算和返回單個值。

2. 函數的優點

  • 代碼復用:函數可以被多次調用,避免重復編寫SQL語句。
  • 性能提升:函數在服務器端執行,減少了網絡傳輸。
  • 邏輯封裝:函數可以封裝復雜的計算邏輯。

3. 創建函數

語法:

CREATE FUNCTION function_name (param1 type, ...)
RETURNS return_type
BEGIN-- SQL語句RETURN value;
END;

4. 調用函數

SELECT function_name(param1, param2, ...);

5. 刪除函數

DROP FUNCTION function_name;

三、實際例子

示例1:存儲過程(插入數據并返回插入的行數)

場景:插入一條用戶數據,并返回插入的行數
-- 創建存儲過程
DELIMITER //CREATE PROCEDURE InsertUser(IN username VARCHAR(50), IN email VARCHAR(100), OUT rows_affected INT)
BEGININSERT INTO users (username, email) VALUES (username, email);SET rows_affected = ROW_COUNT();
END //DELIMITER ;-- 調用存儲過程
CALL InsertUser('Alice', 'alice@example.com', @rows_affected);-- 查看返回的行數
SELECT @rows_affected;

解釋

  • 創建了一個存儲過程InsertUser,接收用戶名和郵箱作為輸入參數,返回插入的行數。
  • 使用ROW_COUNT()函數獲取插入的行數。
  • 調用存儲過程時,使用OUT參數rows_affected接收返回值。

示例2:存儲過程(更新數據并返回受影響的行數)

場景:更新用戶郵箱,并返回受影響的行數
-- 創建存儲過程
DELIMITER //CREATE PROCEDURE UpdateUserEmail(IN user_id INT, IN new_email VARCHAR(100), OUT rows_affected INT)
BEGINUPDATE users SET email = new_email WHERE id = user_id;SET rows_affected = ROW_COUNT();
END //DELIMITER ;-- 調用存儲過程
CALL UpdateUserEmail(1, 'new_email@example.com', @rows_affected);-- 查看返回的行數
SELECT @rows_affected;

解釋

  • 創建了一個存儲過程UpdateUserEmail,接收用戶ID和新郵箱作為輸入參數,返回受影響的行數。
  • 使用ROW_COUNT()函數獲取受影響的行數。
  • 調用存儲過程時,使用OUT參數rows_affected接收返回值。

示例3:存儲過程(事務控制)

場景:從用戶A的賬戶轉賬到用戶B的賬戶
-- 創建存儲過程
DELIMITER //CREATE PROCEDURE TransferMoney(IN from_id INT, IN to_id INT, IN amount DECIMAL(10, 2))
BEGINDECLARE from_balance DECIMAL(10, 2);DECLARE to_balance DECIMAL(10, 2);-- 開始事務START TRANSACTION;-- 檢查用戶A的余額是否足夠SELECT balance INTO from_balance FROM accounts WHERE id = from_id FOR UPDATE;IF from_balance < amount THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Insufficient balance';END IF;-- 扣款UPDATE accounts SET balance = balance - amount WHERE id = from_id;-- 加款UPDATE accounts SET balance = balance + amount WHERE id = to_id;-- 提交事務COMMIT;
END //DELIMITER ;-- 調用存儲過程
CALL TransferMoney(1, 2, 100.00);

解釋

  • 創建了一個存儲過程TransferMoney,接收轉賬的用戶ID、收款的用戶ID和轉賬金額。
  • 使用START TRANSACTIONCOMMIT管理事務。
  • 使用FOR UPDATE鎖定用戶A的賬戶,防止并發問題。
  • 如果用戶A的余額不足,拋出異常。

示例4:函數(計算用戶年齡)

場景:根據用戶的出生日期計算年齡
-- 創建函數
DELIMITER //CREATE FUNCTION CalculateAge(birthdate DATE)
RETURNS INT
BEGINDECLARE age INT;SET age = TIMESTAMPDIFF(YEAR, birthdate, CURDATE());RETURN age;
END //DELIMITER ;-- 調用函數
SELECT id, name, birthdate, CalculateAge(birthdate) AS age FROM users;

解釋

  • 創建了一個函數CalculateAge,接收出生日期作為參數,返回年齡。
  • 使用TIMESTAMPDIFF函數計算當前日期與出生日期之間的年數。
  • 調用函數時,可以直接在SELECT語句中使用。

示例5:函數(計算訂單總價)

場景:根據訂單中的商品數量和單價計算總價
-- 創建函數
DELIMITER //CREATE FUNCTION CalculateOrderTotal(quantity INT, unit_price DECIMAL(10, 2))
RETURNS DECIMAL(10, 2)
BEGINDECLARE total DECIMAL(10, 2);SET total = quantity * unit_price;RETURN total;
END //DELIMITER ;-- 調用函數
SELECT order_id, quantity, unit_price, CalculateOrderTotal(quantity, unit_price) AS total_price
FROM order_items;

解釋

  • 創建了一個函數CalculateOrderTotal,接收商品數量和單價作為參數,返回總價。
  • 調用函數時,可以直接在SELECT語句中使用。

四、總結

存儲過程和函數是MySQL中強大的工具,可以封裝復雜的邏輯,提高代碼的復用性和安全性。存儲過程支持事務控制和多種參數類型,適用于復雜的數據操作。函數則專注于計算和返回單個值,適用于簡單的邏輯封裝。通過合理使用存儲過程和函數,可以顯著提升數據庫的可維護性和性能。

以上就是基于Mysql,有關查詢相關的進階知識,希望對你有所幫助~
后續會連續發布多篇SQL進階相關內容;
期待你的關注,學習更多知識;

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

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

相關文章

CONDA:用于 Co-Salient 目標檢測的壓縮深度關聯學習(總結)

摘要 一 介紹 二 有關工作 三 提出的方法 圖2&#xff1a;我們的凝聚式深度關聯&#xff08;CONDA&#xff09;模型的整體流程圖。具體來說&#xff0c;凝聚式深度關聯&#xff08;CONDA&#xff09;模型首先利用圖像特征來計算超關聯。然后&#xff0c;全像素超關聯由對應誘…

node.js 實戰——(path模塊 知識點學習)

path 模塊 提供了操作路徑的功能 說明path. resolve拼接規范的絕對路徑path. sep獲取操作系統的路徑分隔符path. parse解析路徑并返回對象path. basename獲取路徑的基礎名稱path. dirname獲取路徑的目錄名path. extname獲得路徑的擴展名 resolve 拼接規范的絕對路徑 const…

Kimi做內容社區,劍指小紅書?

原創科技新知AI新科技組作者丨櫻木編輯丨江蘺 主編丨九黎 對于當前融資形勢并不明朗的大模型六小龍來說&#xff0c;該如何生存下去&#xff0c;似乎成了各家急需解決的問題。 根據PitchBook數據&#xff0c;今年一季度風險投資機構在中國AI領域共完成144筆交易&#xff0c;投…

opencv--圖像濾波

圖像濾波 含義 方法 噪聲是怎么產生的 線性濾波 概念 利用窗口對圖像中的像素進行加權求和的濾波方式。 圖像來源于小虎教程。 圖像的濾波是二維濾波的過程。 濾波器窗口&#xff1a; 濾波器窗口&#xff08;也稱為卷積核或模板&#xff09;是一個小的矩陣&#xff08;通常為…

Java 實現SpringContextUtils工具類,手動獲取Bean

SpringContextUtils 工具類實現 下面是一個完整的 Spring 上下文工具類實現&#xff0c;用于從 Spring 容器中獲取 Bean。這個工具類考慮了線程安全、性能優化和易用性&#xff0c;并提供了多種獲取 Bean 的方式。 完整實現代碼 import org.springframework.beans.BeansExce…

基于 Vue 2 開發的分頁卡片列表組件(帶懶加載和點擊事件)

功能目標&#xff1a; CardList.vue 中支持分頁&#xff0c;每頁顯示指定數量的卡片。添加“加載中”動畫。支持懶加載&#xff1a;滾動到底部自動加載下一頁。點擊卡片的事件邏輯由 Card.vue 內部發出&#xff0c;并由 CardList 向上傳遞。 主頁面文件 Home.vue <templat…

【數據結構和算法】6. 哈希表

本文根據 數據結構和算法入門 視頻記錄 文章目錄 1. 哈希表的概念1.1 哈希表的實現方式1.2 哈希函數&#xff08;Hash Function&#xff09;1.3 哈希表支持的操作 2. Java實現 在前幾章的學習中&#xff0c;我們已經了解了數組和鏈表的基本特性&#xff0c;不管是數組還是鏈表…

【python】如何將文件夾及其子文件夾下的所有word文件匯總導出到一個excel文件里?

根據你的需求,這里提供一套完整的Python解決方案,支持遞歸遍歷子文件夾、提取Word文檔內容(段落+表格),并整合到Excel中。以下是代碼實現及詳細說明: 一個單元格一個word的全部內容 完整代碼 # -*- coding: utf-8 -*- import os from docx import Document import pand…

leetcode-位運算

位運算 371. 兩整數之和 題目 給你兩個整數 a 和 b &#xff0c;不使用 運算符 和 - &#xff0c;計算并返回兩整數之和。 示例 1&#xff1a; 輸入&#xff1a; a 1, b 2 輸出&#xff1a; 3 示例 2&#xff1a; 輸入&#xff1a; a 2, b 3 輸出&#xff1a; 5 提示&am…

飛帆控件:在編輯模式下額外加載的庫

飛帆是一個自由的控件設計平臺。在飛帆中&#xff0c;我們可以很方便地創建基于 Vue 2 組件的控件&#xff0c;并使用控件來搭建網頁。 他山之石&#xff0c;可以攻玉。在創建控件中&#xff0c;使用 js 、css 依賴庫能讓我們的控件更強大。 有些時候&#xff0c;在編輯模式下…

GPLT-2025年第十屆團體程序設計天梯賽總決賽題解(共計266分)

今天偶然發現天梯賽的代碼還保存著&#xff0c;于是決定寫下這篇題解&#xff0c;也算是復盤一下了 L1本來是打算寫的穩妥點&#xff0c;最后在L1-6又想省時間&#xff0c;又忘記了insert&#xff0c;replace這些方法怎么用&#xff0c;也不想花時間寫一個文件測試&#xff0c…

編碼轉換器

大批量轉換編碼 可以將整個工程文件夾從GB18030轉為UTF-8 使用Qt C制作 項目背景 比較老的工程&#xff0c;尤其是keil嵌入式的工程&#xff0c;其文本文件&#xff08;.c、.cpp、.h、.txt、……&#xff09;編碼為gb2312&#xff0c;這為移植維護等帶來了不便。現在uit-8用…

STL 核心模塊

很好&#xff01;你想深入 STL&#xff08;Standard Template Library&#xff09;和容器算法&#xff0c;是學習 C 非常關鍵的一步。下面我給你整理一份STL 容器 算法的入門指南&#xff0c;適合從零起步掌握這部分內容。 &#x1f31f; 一、STL 核心模塊 STL 分為三大塊&am…

2024沈陽區域賽,D - Dot Product Game

題目鏈接 樹狀數組求逆序對 #include<bits/stdc.h> using namespace std; using lllong long; typedef pair<int,int>PII; typedef priority_queue<int> upq; typedef priority_queue<int,vector<int>,greater<int>> dpq; const int M99…

簡易博客點贊系統實現

簡易博客點贊系統 好久沒寫 Java 了&#xff0c;整個簡單的項目進行康復訓練。 基于 Spring Boot SSM MySQL Mybatis-Plus Knife4j Swagger 的一個簡易博客點贊系統 開源地址&#xff1a;https://github.com/FangMoyu/simple-thumb 功能 登錄獲取當前登錄用戶獲取博客…

一個既簡單又詭異的問題

public class DaYaoGuai {static String s;public static void main(String[] args) {Thread t1 new Thread(){Overridepublic void run() {try {Thread.sleep(1000);} catch (InterruptedException e) {throw new RuntimeException(e);}s"深圳";}};t1.start();Thre…

使用docker在manjaro linux系統上運行windows和ubuntu

因為最近項目必須要使用指定版本的solidworks和maxwell&#xff08;都只能在win系統上使用&#xff09;, 且目前的ubuntu容器是沒有桌面的&#xff0c;導致我運行不了一些帶圖形的ros2功能。無奈之下&#xff0c;決定使用docker-compose寫一下配置文件&#xff0c;徹底解決問題…

Elasticsearch中的_source字段講解

_source 在 Elasticsearch 查詢中用于限制返回的字段,類似于 SQL 中的 SELECT 指定列。 代碼示例: esSearchResults = es_service.search_documents({"query": {"terms": {"file_id":

【論文閱讀20】-CNN-Attention-BiGRU-滑坡預測(2025-03)

這篇論文主要探討了基于深度學習的滑坡位移預測模型&#xff0c;結合了MT-InSAR&#xff08;多時相合成孔徑雷達干涉測量&#xff09;觀測數據&#xff0c;提出了一種具有可解釋性的滑坡位移預測方法。 [1] Zhou C, Ye M, Xia Z, et al. An interpretable attention-based deep…

C++ 的 IO 流

&#x1f4ac; &#xff1a;如果你在閱讀過程中有任何疑問或想要進一步探討的內容&#xff0c;歡迎在評論區暢所欲言&#xff01;我們一起學習、共同成長~&#xff01; &#x1f44d; &#xff1a;如果你覺得這篇文章還不錯&#xff0c;不妨順手點個贊、加入收藏&#xff0c;并…