데이터 베이스 MySQL 튜토리얼 存储程序(1)——MYSQL_MySQL

存储程序(1)——MYSQL_MySQL

May 27, 2016 pm 02:12 PM
프로그램

bitsCN.com

MySQL支持把几种对象存放在服务器端供以后使用。这几种对象有一些可以根据情况通过程序代码调用,有一些会在数据表被修改时自动执行,还有一些可以在预定时刻自动执行。它们包括以下几种:

1.存储函数(stored function)。返回一个计算结果,该结果可以用在表达式里。
2.存储过程(stored procedure)。不直接返回一个结果,但可以用来完成一般的运算或是生成一个结果集并传递回客户。
3.触发器(trigger)。与数据表相关联,当那个数据表被工NSERT、DELETE或UPDATE语句修改时,触发器将自动执行。
4.事件(event)。根据时间表在预定时刻自动执行。

MySQL对存储函数和存储过程的支持始于5.0.0版本,对触发器和事件的支持分别始于5.0.2版本和5.1.6版本。存储程序有以下优点和能力:

1.存储程序对象的可执行部分可以用复合语句来编写,复合语句对SQL语法进行了扩展,可以包括代码块、循环和条件语句。
2.存储程序都被保存在服务器端,定义它们所需要的代码只需在它们被创建时通过网络传递一次,而不是每次执行都要传递一次。这大大减少了开销。
3.它们可以把复杂的计算封装为程序单元,而你可以简单地通过程序单元的名字来调用它们。你甚至可以把一组存储程序打包为一个“函数库”供其他应用程序调用。
4.它们提供了一种错误处理机制。
5.它们可以提高数据库的安全性。你可以通过选择存储程序执行时所需的权限下来对敏感数据的访问情况进行限制和调控。

存储程序。泛指各种类型的存储对象(存储函数、存储过程、触发器、事件)。存储例程(stored routine ),特指存储函数和存储过程。这两种对象的定义语法很相似,所以很自然地把它们放在一起讨论。在开始讨论各种类型的存储程序之前,我们首先学习一下:复合语句。

1.复合语句和语句分隔符

简单的存储程序只包含一条SQL语句,在编写时不需要特殊对待。下面的存储过程使用了一条SELECT语句来列出sampdb数据库里的数据表的名字:

PROCEDURE sampdb_tables()SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLESWHERE TABLE_SCHEMA=’sampdb’ ORDER BY TABLE_NAME;
로그인 후 복사

不过,存储程序并非只能包含一条简单的SQL语句。它们可以包含多条SQL语句,可以使用局部变量、条件语句、循环和嵌套语句块等多种语法构造。要使用这些构造编写存储程序,就需要用到复合语句。复合语句由BEGIN开头,END结束,在它们之间可以写出任意数量的语句,这些语句构成了一个语句块。下面的存储过程将显示一条欢迎消息,其中有你的用户名;如果你是一位匿名用户,用户名将是“earthing":

CREATE PROCEDURE greetings()BEGIN    #77=16  for username+60 for hostname+1 for '@'    DECLARE user CHAR(77) CHARACTER SET utf8;    SET user = (SELECT CURRENT USER());    IF INSTR(user,’@’)>0 THEN    #返回字符串在某一个字段的内容中的位置, 没有找到字符串返回0,否则返回位置(从1开始)        SET user=SUBSTRING_INDEX(user, '@', 1);    END IF;    IF user = '' THEN        SET user='earthling';    END IF;    SELECT CONCAT('Greetings,',user, '!') AS greeting;END;
로그인 후 복사

在使用复合语句时,必须考虑和解决这样一个问题:复合语句块里的语句必须以分号(;)彼此隔开,但因为分号同时也是mysql程序默认使用的语句分隔符,所以在使用mysql程序定义存储程序时会发生冲突。
解决这个问题的办法是使用delimiter命令把mysql程序的语句分隔符重定义为另一个字符或字符串,它必须是在存储例程的定义里没有出现过的。这样一来,mysql程序就不会把分号解释为语句终止符了,它将把整个对象定义作为一条语句传递给服务器。在定义完存储程序之后,可以把mysql程序的语句终止符重新定义为分号。

use weibo;delimiter $CREATE PROCEDURE show_times()BEGIN    SELECT 'Local time is:', CURRENT_TIMESTAMP;    SELECT 'UTC time is:', UTC_TIMESTAMP;END$delimiter ;-- delimiter后空格加分号,将分号设置为分隔符CALL show_times();
로그인 후 복사

定义一个存储过程时把mysql程序的默认分隔符临时改变为$,然后在恢复了mysql程序的默认分隔符之后执行了那个存储过程:

Local time is:2014-01-15 23:00:26 
image

分隔符不必非得是$字符,也不必非得是单个的字符:

delimiter EOF
로그인 후 복사

这里的原则是:只要在某个存储程序内部的语句里会用到分号,就应该在定义这个存储程序时临时改变mysql程序的分隔符。

2.存储函数和存储过程

存储函数将向调用者返回一个计算结果,这个结果可以用在表达式里(就像COS()或HEX()这样的内建函数那样)。存储过程需要使用CALL语句来调用,是一个独立的操作,不能用在表达式里。使用存储过程的情况主要有两种:(1)只需通过运算来实现某种效果或动作而无需返回一个值,(2)运算会返回多个结果集(函数做不到这一点)。这只是些指导性建议,不是硬性规定。
比如说,如果你需要返回两个或更多的值,就不能使用函数。但你可以使用一个过程,因为过程支持的参数类型允许它们的值在过程执行期间被设置,而调用者可以在过程返回后去访问那些值。

存储函数要用CREATE FUNCTION语句来创建,存储过程要用CREATE PROCEDURE语句来创建。下面的例子将创建一个函数,该函数有一个代表着年份的整数参数。(为了与数据表或数据列的名字有所区别,参数命名时将使用p_前缀)。

delimiter $CREATE FUNCTION count_born_in_year(p_year INT)RETURNS INTREADS SQL DATABEGIN    RETURN (SELECT COUNT(*) FROM president WHERE YEAR(birtb) = p_year);END$delimiter ;
로그인 후 복사

这个函数有一条用来表明其返回值数据类型的RETURNS子句和一个用来计算那个值的函数体。函数体至少需要包含一条RETURN语句,用来向调用者返回一个值。把计算定义为函数的好处是可以方便地执行它而无须每次都写出所有的逻辑,你可以像使用内建函数那样来调用存储函数:

SELECT count_born_in_year(1990);
로그인 후 복사

你无法让一个给定的函数返回多个值。你可以编写任意多个函数,然后在同一条语句里调用它们全体。另一个办法是使用一个存储过程并通过它的OUT参数“返回”多个值。存储过程负责计算那些值并把它们赋值给相应的参数,而那些参数可以在过程返回后由调用者访问。如果你定义了一个与某个MySQL内建函数同名的存储函数,在调用它时就必须用数据库的名字对该函数的名字进行限定以避免歧义。

存储过程和存储函数很相似,但它不返回值。因此,它没有RETURNS子句或任何RETURN语句。下面这个简单的存储过程和count_born_in_year()函数很相似,它将显示一个结果集而不是把计算结果作为其返回值。

delimiter $CREATE PROCEDURE show_born_in_year(p_year INT)BEGIN    SELECT first_name, last_name, birth, death    FROM president    WHERE YEAR(birth)=P_year;END$delimiter ;
로그인 후 복사

与存储函数不同,存储过程不能用在表达式里,它们只能通过CALL语句来调用。如下所示:

CALL show_born_in_year(1990);
로그인 후 복사

前面的例子都是选取信息,但存储例程还可以用来修改数据表,如下例所示:

delimiter $CREATE PROCEDURE update_expiration (p_id INT UNSIGNED, p_date DATE)BEGIN    UPDATE member SET expiration=p_date WHERE member_id=p_id;END$delimiter ;
로그인 후 복사

存储函数必须遵守这样一条限制:不允许对调用本函数的语句正在读或写的数据表进行修改。存储过程通常没有这个限制,但如果它们是从存储函数里被调用,就需要遵守这条限制。

3.存储函数和存储过程的权限

存储函数和存储过程属于数据库。要想创建存储函数或存储过程,必须拥有那个数据库的CREATE ROUTINE权限。在默认的情况下,当你创建一个存储例程时,服务器将自动地把EXECUTE和ALTER ROUTINE权限授予你(如果你还没有获得这些权限),这样你才可以执行那个例程或删除它。当你删除那个例程时,服务器将自动撤销那些权限。如果你不想使用这种自动化的权限授予/撤销机制,把automatic_sp_privileges系统变量设置为0即可。

如果服务器启用了二进制日志功能,存储函数还需要遵守一些额外的限制条件(不允许创建不确定或是会修改数据的存储函数)以保证二进制日志能够安全地完成备份和复制操作。这些限制条件如下:
1.如果log_bin_trust_function_creators系统变量没有被激活,你就必须具备SUPER权限才能创建存储函数。在此前提下,你创建的每一个函数都必须是确定的,并且不得修改数据。为了表明这一点,需要使用DETERMINISTIC、NO SQL或READS SQL DATA之一来定义存储函数。
2.如果log bin_trust_function_creators系统变量已被激活,则没有任何限制。只有当你可以相信MySQL服务器上的所有用户都不会去定义不安全的存储函数时,这种设置才是最适当的。

与log_bin_trust_function_creators系统变量有关的限制条件同样适用于触发器的创建工作。

4.存储过程的参数类型

存储过程的参数分为3种类型。对于IN参数,调用者把一个值传递给过程,过程可以对这个值进行修改,但任何修改在过程返回后对调用者是不可见的。OUT参数刚好相反,过程把一个值赋值给OUT参数,这个值在过程返回后可以由调用者访问。INOUT参数允许调用者向过程传递一个值,然后再取回一个值。
要想明确地为参数指定类型,在参数表里把IN, OUT或INOUT写在参数名字前面即可。如果没有为参数指定类型,其默认类型将是IN。

在使用OUT或INOUT参数时,在调用过程时需要给出一个变量名。过程可以设置参数的值,相应的变量将在过程返回时获得那个值。如果想让某个存储过程返回多个结果值,OUT和INOUT参数类型将非常有用(存储函数只能返回一个值,不能胜任)。下面的过程演示了OUT参数的用法。它将分别统计出student数据表里的男生和女生人数并通过它的参数返回这两个计数值,让调用者可以访问它们:

delimiter $CREATE PROCEDURE count_students_by_sex(OUT p_male INT, OUT p_female INT)BEGIN    SELECT COUNT(*) FROM student WHERE sex= 'F' INTO p_female;    SELECT COUNT(*) FROM student WHERE sex= 'F' INTO p_female;END$delimiter ;
로그인 후 복사

在调用这个过程时,请把各个参数替换为相应的用户定义变量。这个过程将把计数值放到这些参数里,在它返回之后,那些变量将包含计数值:

CALL count_students_by_sex(@mcoant, @fcount);SELECT 'Number of male students:',@mcount;
로그인 후 복사

IN、OUT和INOUT关键字不适用于存储函数、触发器或事件。对于存储函数,所有的参数都像IN参数。触发器和事件则根本没有任何参数。下一部分介绍:触发器和事件。

bitsCN.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

iPhone에서 Google 지도를 기본 지도로 설정하는 방법 iPhone에서 Google 지도를 기본 지도로 설정하는 방법 Apr 17, 2024 pm 07:34 PM

iPhone의 기본 지도는 Apple의 독점 위치 정보 제공업체인 지도입니다. 지도가 점점 좋아지고 있지만 미국 이외의 지역에서는 잘 작동하지 않습니다. Google 지도와 비교하면 아무것도 제공할 수 없습니다. 이 기사에서는 Google 지도를 사용하여 iPhone의 기본 지도로 만드는 실행 가능한 단계에 대해 설명합니다. iPhone에서 Google 지도를 기본 지도로 설정하는 방법 Google 지도를 휴대전화의 기본 지도 앱으로 설정하는 것은 생각보다 쉽습니다. 아래 단계를 따르십시오. – 전제 조건 단계 – 휴대폰에 Gmail이 설치되어 있어야 합니다. 1단계 – AppStore를 엽니다. 2단계 – “Gmail”을 검색하세요. 3단계 - Gmail 앱 옆을 클릭하세요.

수정: Windows 작업 스케줄러에서 운영자 거부 요청 오류 수정: Windows 작업 스케줄러에서 운영자 거부 요청 오류 Aug 01, 2023 pm 08:43 PM

작업을 자동화하고 여러 시스템을 관리하기 위해 임무 계획 소프트웨어는 특히 시스템 관리자에게 유용한 도구입니다. Windows 작업 스케줄러는 작업을 완벽하게 수행하지만 최근 많은 사람들이 운영자 거부 요청 오류를 보고했습니다. 이 문제는 운영 체제의 모든 반복에 존재하며 널리 보고되고 다루어졌음에도 불구하고 효과적인 해결책은 없습니다. 다른 사람들에게 실제로 효과가 있을 수 있는 것이 무엇인지 알아보려면 계속해서 읽어보세요! 운영자 또는 관리자가 거부한 작업 스케줄러 0x800710e0의 요청은 무엇입니까? 작업 스케줄러를 사용하면 사용자 입력 없이 다양한 작업과 응용 프로그램을 자동화할 수 있습니다. 이를 사용하여 특정 애플리케이션을 예약 및 구성하고, 자동 알림을 구성하고, 메시지 전달을 돕는 등의 작업을 할 수 있습니다. 그것

Windows 10 및 11에서 얼굴별로 사진을 정렬하는 방법 Windows 10 및 11에서 얼굴별로 사진을 정렬하는 방법 Aug 08, 2023 pm 10:41 PM

Windows의 작동은 사용자 경험을 향상시키는 매력적인 기능을 포함하여 모든 버전에서 점점 더 좋아지고 있습니다. 사용자가 Windows 10 및 11에서 탐색하고 싶은 기능 중 하나는 사진을 얼굴별로 정렬하는 기능입니다. 이 기능을 사용하면 얼굴 인식을 사용하여 친구와 가족의 사진을 그룹화할 수 있습니다. 재미있을 것 같죠? 이 기능을 활용하는 방법을 알아보려면 계속 읽어보세요. Windows에서 사진을 얼굴별로 그룹화할 수 있나요? 예, Windows 10 및 11에서 사진 앱을 사용하여 사진을 얼굴별로 그룹화할 수 있습니다. 하지만 포토 앱 버전에서는 이 기능을 사용할 수 없습니다. 또한 인물 탭을 사용하여 이러한 사진을 연락처에 연결할 수 있습니다. 따라서 이 기능을 사용하면 다음과 같은 작업을 수행할 수 있습니다.

특정 앱에 대해 iPhone 방향 잠금을 자동으로 전환하는 방법 특정 앱에 대해 iPhone 방향 잠금을 자동으로 전환하는 방법 Jun 06, 2023 am 08:22 AM

iOS에서는 iPhone을 세로에서 가로로 회전하면 많은 앱이 서로 다른 보기를 표시합니다. 앱과 사용 방법에 따라 이 동작이 항상 바람직한 것은 아니므로 Apple은 제어 센터에 방향 잠금 옵션을 포함합니다. 그러나 일부 앱은 방향 잠금이 비활성화된 상태에서 더 유용하게 작동합니다. YouTube나 사진 앱을 생각해 보세요. 기기를 가로 방향으로 회전하면 전체 화면 보기 환경이 더 좋아집니다. 잠금 상태를 유지하려면 이러한 유형의 앱을 열 때마다 전체 화면 경험을 얻기 위해 제어 센터에서 해당 기능을 비활성화해야 합니다. 그런 다음 앱을 닫을 때 방향 잠금을 다시 켜야 한다는 것을 기억해야 하는데 이는 이상적이지 않습니다. 다행히도 다음을 만들 수 있습니다.

iPhone에 시계 앱이 없습니다. 해결 방법 iPhone에 시계 앱이 없습니다. 해결 방법 May 03, 2024 pm 09:19 PM

휴대폰에 시계 앱이 없나요? 날짜와 시간은 iPhone의 상태 표시줄에 계속 표시됩니다. 그러나 시계 앱이 없으면 세계 시계, 스톱워치, 알람 시계 및 기타 여러 기능을 사용할 수 없습니다. 따라서 누락된 시계 앱을 수정하는 것이 해야 할 일 목록의 맨 위에 있어야 합니다. 이러한 솔루션은 이 문제를 해결하는 데 도움이 될 수 있습니다. 수정 1 - 시계 앱 배치 실수로 홈 화면에서 시계 앱을 제거한 경우 시계 앱을 다시 제자리에 배치할 수 있습니다. 1단계 – iPhone을 잠금 해제하고 앱 라이브러리 페이지에 도달할 때까지 왼쪽으로 스와이프합니다. 2단계 – 다음으로 검색창에 “시계”를 검색하세요. 3단계 – 검색 결과 아래에 “시계”가 표시되면 길게 누르고

C++로 간단한 카운트다운 프로그램을 작성하는 방법은 무엇입니까? C++로 간단한 카운트다운 프로그램을 작성하는 방법은 무엇입니까? Nov 03, 2023 pm 01:39 PM

C++는 카운트다운 프로그램을 작성하는 데 매우 편리하고 실용적인 프로그래밍 언어로 널리 사용됩니다. 카운트다운 프로그램은 매우 정확한 시간 계산 및 카운트다운 기능을 제공할 수 있는 일반적인 애플리케이션입니다. 이 기사에서는 C++를 사용하여 간단한 카운트다운 프로그램을 작성하는 방법을 소개합니다. 카운트다운 프로그램 구현의 핵심은 타이머를 사용하여 시간의 경과를 계산하는 것입니다. C++에서는 time.h 헤더 파일의 함수를 사용하여 타이머 함수를 구현할 수 있습니다. 다음은 간단한 카운트다운 프로그램의 코드입니다.

작업 스케줄러를 사용하여 웹사이트를 여는 방법 작업 스케줄러를 사용하여 웹사이트를 여는 방법 Oct 02, 2023 pm 11:13 PM

매일 같은 시간에 같은 웹사이트를 자주 방문하시나요? 이로 인해 여러 브라우저 탭을 열어두고 일상적인 작업을 수행하는 동안 브라우저가 복잡해지는 데 많은 시간을 소비하게 될 수 있습니다. 그렇다면 브라우저를 수동으로 실행할 필요 없이 열어보는 것은 어떨까요? 매우 간단하며 아래와 같이 타사 앱을 다운로드할 필요가 없습니다. 웹사이트를 열려면 작업 스케줄러를 어떻게 설정하나요? 키를 누르고 검색 상자에 작업 스케줄러를 입력한 다음 열기를 클릭합니다. Windows 오른쪽 사이드바에서 기본 작업 생성 옵션을 클릭합니다. 이름 필드에 열려는 웹사이트의 이름을 입력하고 다음을 클릭하세요. 그런 다음 트리거에서 시간 빈도를 클릭하고 다음을 클릭합니다. 이벤트를 반복할 기간을 선택하고 다음을 클릭하세요. 활성화 선택

iOS 17: 메시지에서 iMessage 앱을 구성하는 방법 iOS 17: 메시지에서 iMessage 앱을 구성하는 방법 Sep 18, 2023 pm 05:25 PM

iOS 17에서 Apple은 몇 가지 새로운 메시징 기능을 추가했을 뿐만 아니라 메시지 앱의 디자인을 조정하여 더욱 깔끔한 모습을 제공했습니다. 카메라 및 사진 옵션과 같은 모든 iMessage 앱과 도구는 이제 키보드 위와 텍스트 입력 필드 왼쪽에 있는 "+" 버튼을 탭하여 접근할 수 있습니다. "+" 버튼을 클릭하면 기본 옵션 순서가 포함된 메뉴 열이 나타납니다. 맨 위에서부터 카메라, 사진, 스티커, 현금(가능한 경우), 오디오, 위치가 있습니다. 맨 아래에는 "더 보기" 버튼이 있는데, 이 버튼을 누르면 설치된 다른 메시징 앱이 표시됩니다(위로 스와이프하여 숨겨진 목록을 표시할 수도 있습니다). iMessage 앱을 재구성하는 방법 다음과 같이 할 수 있습니다.

See all articles