我在看MySQL的过程和函数,它们之间真实的区别是什么?它们看起来很相似,但功能有更多的限制。我可能错了,但似乎过程可以做任何事情,而且比函数做得更多。为什么/什么时候我会使用过程而不是函数?
7z5jn7bk1#
过程和函数之间最常见的区别是它们的调用方式不同,目的也不同:
1.过程不返回值,而是用CALL语句调用它来执行操作,如修改表或处理检索到的记录。1.函数在表达式中被调用,并直接向调用方返回一个值以在表达式中使用。1.不能用CALL语句调用函数,也不能在表达式中调用过程。
创建例程的方法对于过程和函数来说有些不同:
1.过程参数可以定义为仅输入、仅输出或两者兼有。这意味着过程可以使用输出参数将值传递回调用方。这些值可以在CALL语句之后的语句中访问。函数只有输入参数。因此,尽管过程和函数都可以有参数,但过程参数声明与函数的声明不同。
CALL statement
如果参数名前没有给出关键字,则默认为IN参数。**存储函数的参数前不带IN、OUT或INOUT。**所有函数参数都被视为IN参数。
定义存储过程或函数时,请分别使用CREATE PROCEDURE或CREATE FUNCTION:
CREATE PROCEDURE proc_name ([parameters]) [characteristics] routine_body CREATE FUNCTION func_name ([parameters]) RETURNS data_type // diffrent [characteristics] routine_body
字符串MySQL对存储过程(不是函数)的扩展是,一个过程可以生成一个结果集,甚至多个结果集,调用者处理这些结果集的方式与SELECT语句的结果相同。但是,这样的结果集的内容不能直接在表达式中使用。
存储例程(指存储过程和存储函数)**与特定的数据库相关联,就像表或视图一样。**当您删除数据库时,数据库中的任何存储例程也会被删除。**存储过程和函数不共享相同的命名空间。**在数据库中可能有同名的过程和函数。在存储过程中可以使用动态SQL,但不能在函数或触发器中使用。
SQL预准备语句(EXECUTE,DEALLOCATE EXECUTE)可以在存储过程中使用,但不能在存储函数或触发器中使用。因此,存储函数和触发器不能使用动态SQL(将语句构造为字符串,然后执行它们)。(MySQL存储例程中的动态SQL)
FUNCTION和STORED PROCEDURE之间的一些更有趣的区别:
1.(* 这一点是从博客文章复制的。)存储过程是预编译的执行计划,而函数不是。函数在运行时解析和编译。存储过程,存储为数据库中的伪代码,即编译形式。1.( 我不确定这一点。*)存储过程具有安全性,减少了网络流量,而且我们可以在任何数量的应用程序中同时调用存储过程。reference1.函数通常用于计算,而过程通常用于执行业务逻辑。1.函数不能影响数据库的状态(函数中不允许执行显式或隐式提交或回滚的语句),而存储过程可以使用提交等方式影响数据库的状态。参考:J.1.对存储的进程和触发器的限制1.函数不能使用FLUSH语句,而存储过程可以。1.存储函数不能是递归的,而存储过程可以是递归的。注意:默认情况下,递归存储过程是禁用的,但可以在服务器上通过将max_sp_recursion_depth服务器系统变量设置为非零值来启用。有关详细信息,请参见第5.2.3节“系统变量”。1.在存储的函数或触发器中,不允许修改调用函数或触发器的语句已经使用(用于阅读或写入)的表。
备注:虽然某些限制通常适用于存储函数和触发器,但不适用于存储过程,但如果从存储函数或触发器中调用存储过程,则这些限制确实适用于存储过程。例如,尽管可以在存储过程中使用FLUSH,但不能从存储函数或触发器调用此类存储过程。
yx2lnoni2#
你不能将存储过程与普通的SQL混合在一起,而存储函数可以。例如,如果get_foo()是一个过程,则SELECT get_foo(myColumn) FROM mytable无效,但如果get_foo()是一个函数,则可以这样做。代价是函数比过程有更多的限制。
get_foo()
SELECT get_foo(myColumn) FROM mytable
atmip9wb3#
一个显著的区别是,您可以在SQL查询中包含function,但stored procedures只能通过CALL语句调用:UDF示例:
CALL
CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50) DETERMINISTIC RETURN CONCAT('Hello, ',s,'!'); Query OK, 0 rows affected (0.00 sec) CREATE TABLE names (id int, name varchar(20)); INSERT INTO names VALUES (1, 'Bob'); INSERT INTO names VALUES (2, 'John'); INSERT INTO names VALUES (3, 'Paul'); SELECT hello(name) FROM names; +--------------+ | hello(name) | +--------------+ | Hello, Bob! | | Hello, John! | | Hello, Paul! | +--------------+ 3 rows in set (0.00 sec)
字符串Sproc示例:
delimiter // CREATE PROCEDURE simpleproc (IN s CHAR(100)) BEGIN SELECT CONCAT('Hello, ', s, '!'); END// Query OK, 0 rows affected (0.00 sec) delimiter ; CALL simpleproc('World'); +---------------------------+ | CONCAT('Hello, ', s, '!') | +---------------------------+ | Hello, World! | +---------------------------+ 1 row in set (0.00 sec)
型
bbuxkriu4#
存储函数可以在查询中使用,然后可以将其应用于每一行,或应用于WHERE子句中。使用CALL查询执行过程。
pepwfjgg5#
存储过程可以递归调用,但存储函数不能
uklbhaso6#
除了上面给出的答案,我想补充一点,函数可以与其他函数和表达式组合使用,也可以以嵌套的方式使用(简而言之,它们可以以非常复杂的形式使用,以完成我们想要的工作)。同样的事情可以在过程中实现,但是在过程中我们必须完成在该过程中完成的所有工作,这意味着在一个整体的时尚代码中。(而在函数中,可以为每个任务;可以实现一个新的函数)。所以最后我们可以通过使用不同函数的组合来完成任务。
drkbr07n7#
当不使用transaction和/或不返回多个值时,应该使用function。当使用transaction和/或返回多个值时,应该使用procedure。
BEGIN ... END
$$
DETERMINISTIC
NOT DETERMINISTIC
SELECT
INTO
IN
OUT
INOUT
RETURN
7条答案
按热度按时间7z5jn7bk1#
过程和函数之间最常见的区别是它们的调用方式不同,目的也不同:
1.过程不返回值,而是用CALL语句调用它来执行操作,如修改表或处理检索到的记录。
1.函数在表达式中被调用,并直接向调用方返回一个值以在表达式中使用。
1.不能用CALL语句调用函数,也不能在表达式中调用过程。
创建例程的方法对于过程和函数来说有些不同:
1.过程参数可以定义为仅输入、仅输出或两者兼有。这意味着过程可以使用输出参数将值传递回调用方。这些值可以在CALL语句之后的语句中访问。函数只有输入参数。因此,尽管过程和函数都可以有参数,但过程参数声明与函数的声明不同。
CALL statement
。要调用存储函数,请在表达式中引用它。该函数在表达式计算期间返回一个值。如果参数名前没有给出关键字,则默认为IN参数。**存储函数的参数前不带IN、OUT或INOUT。**所有函数参数都被视为IN参数。
定义存储过程或函数时,请分别使用CREATE PROCEDURE或CREATE FUNCTION:
字符串
MySQL对存储过程(不是函数)的扩展是,一个过程可以生成一个结果集,甚至多个结果集,调用者处理这些结果集的方式与SELECT语句的结果相同。但是,这样的结果集的内容不能直接在表达式中使用。
存储例程(指存储过程和存储函数)**与特定的数据库相关联,就像表或视图一样。**当您删除数据库时,数据库中的任何存储例程也会被删除。
**存储过程和函数不共享相同的命名空间。**在数据库中可能有同名的过程和函数。
在存储过程中可以使用动态SQL,但不能在函数或触发器中使用。
SQL预准备语句(EXECUTE,DEALLOCATE EXECUTE)可以在存储过程中使用,但不能在存储函数或触发器中使用。因此,存储函数和触发器不能使用动态SQL(将语句构造为字符串,然后执行它们)。(MySQL存储例程中的动态SQL)
FUNCTION和STORED PROCEDURE之间的一些更有趣的区别:
1.(* 这一点是从博客文章复制的。)存储过程是预编译的执行计划,而函数不是。函数在运行时解析和编译。存储过程,存储为数据库中的伪代码,即编译形式。
1.( 我不确定这一点。*)
存储过程具有安全性,减少了网络流量,而且我们可以在任何数量的应用程序中同时调用存储过程。reference
1.函数通常用于计算,而过程通常用于执行业务逻辑。
1.函数不能影响数据库的状态(函数中不允许执行显式或隐式提交或回滚的语句),而存储过程可以使用提交等方式影响数据库的状态。
参考:J.1.对存储的进程和触发器的限制
1.函数不能使用FLUSH语句,而存储过程可以。
1.存储函数不能是递归的,而存储过程可以是递归的。注意:默认情况下,递归存储过程是禁用的,但可以在服务器上通过将max_sp_recursion_depth服务器系统变量设置为非零值来启用。有关详细信息,请参见第5.2.3节“系统变量”。
1.在存储的函数或触发器中,不允许修改调用函数或触发器的语句已经使用(用于阅读或写入)的表。
备注:虽然某些限制通常适用于存储函数和触发器,但不适用于存储过程,但如果从存储函数或触发器中调用存储过程,则这些限制确实适用于存储过程。例如,尽管可以在存储过程中使用FLUSH,但不能从存储函数或触发器调用此类存储过程。
yx2lnoni2#
你不能将存储过程与普通的SQL混合在一起,而存储函数可以。
例如,如果
get_foo()
是一个过程,则SELECT get_foo(myColumn) FROM mytable
无效,但如果get_foo()
是一个函数,则可以这样做。代价是函数比过程有更多的限制。atmip9wb3#
一个显著的区别是,您可以在SQL查询中包含function,但stored procedures只能通过
CALL
语句调用:UDF示例:
字符串
Sproc示例:
型
bbuxkriu4#
存储函数可以在查询中使用,然后可以将其应用于每一行,或应用于WHERE子句中。
使用CALL查询执行过程。
pepwfjgg5#
存储过程可以递归调用,但存储函数不能
uklbhaso6#
除了上面给出的答案,我想补充一点,
函数可以与其他函数和表达式组合使用,也可以以嵌套的方式使用(简而言之,它们可以以非常复杂的形式使用,以完成我们想要的工作)。
同样的事情可以在过程中实现,但是在过程中我们必须完成在该过程中完成的所有工作,这意味着在一个整体的时尚代码中。(而在函数中,可以为每个任务;可以实现一个新的函数)。所以最后我们可以通过使用不同函数的组合来完成任务。
drkbr07n7#
当不使用transaction和/或不返回多个值时,应该使用function。
当使用transaction和/或返回多个值时,应该使用procedure。
一个函数:
BEGIN ... END
语句的语句会出错。$$
而不会出错。DETERMINISTIC
或NOT DETERMINISTIC
。* 如果其中任何一个没有设置,则NOT DETERMINISTIC
被隐式设置。SELECT
没有INTO
,否则有错误。一个过程:
BEGIN ... END
语句中可以有零个或多个SQL语句。* 没有BEGIN ... END
语句的语句会出错。BEGIN ... END
语句,没有错误地将$$
更改为$$
。IN
、OUT
和INOUT
,也可以没有这些参数。IN
和INOUT
参数的值。OUT
和INOUT
参数向调用者返回零个或多个值。RETURN
语句,否则会出现错误。