我学习函数和存储过程已经有一段时间了,但是我不知道为什么以及何时应该使用函数或存储过程。在我看来,它们看起来一样,也许是因为我对此有些新手。
有人可以告诉我为什么吗?
我学习函数和存储过程已经有一段时间了,但是我不知道为什么以及何时应该使用函数或存储过程。在我看来,它们看起来一样,也许是因为我对此有些新手。
有人可以告诉我为什么吗?
Answers:
函数是计算值,不能对它们执行永久性的环境更改SQL Server
(即,不执行INSERT
或UPDATE
不允许执行任何声明)。
如果函数SQL
返回标量值,则可以在语句中内联使用;如果返回结果集,则可以在函数中加入函数。
注释总结了答案,这一点值得一提。感谢@Sean K Anderson:
函数遵循计算机科学的定义,因为它们必须返回一个值,并且不能更改作为参数(自变量)接收的数据。函数不允许更改任何内容,必须至少具有一个参数,并且它们必须返回一个值。存储的proc不必具有参数,可以更改数据库对象,也不必返回值。
如何SQL
从存储过程调用 函数以及何时使用函数而不是存储过程。
嗨,朋友们,今天我们将讨论何时使用存储过程以及何时使用函数。在简单团队中如果要计算一些值,它将返回一个值,因此不是必需的:
https://programmingtechtutorial.blogspot.com/2020/01/when-use-storeprocedure-and-when-use.html
SP和UDF之间的区别如下:
+---------------------------------+----------------------------------------+
| Stored Procedure (SP) | Function (UDF - User Defined |
| | Function) |
+---------------------------------+----------------------------------------+
| SP can return zero , single or | Function must return a single value |
| multiple values. | (which may be a scalar or a table). |
+---------------------------------+----------------------------------------+
| We can use transaction in SP. | We can't use transaction in UDF. |
+---------------------------------+----------------------------------------+
| SP can have input/output | Only input parameter. |
| parameter. | |
+---------------------------------+----------------------------------------+
| We can call function from SP. | We can't call SP from function. |
+---------------------------------+----------------------------------------+
| We can't use SP in SELECT/ | We can use UDF in SELECT/ WHERE/ |
| WHERE/ HAVING statement. | HAVING statement. |
+---------------------------------+----------------------------------------+
| We can use exception handling | We can't use Try-Catch block in UDF. |
| using Try-Catch block in SP. | |
+---------------------------------+----------------------------------------+
函数和存储过程用于不同的目的。尽管这不是最好的类比,但函数可以从字面上看成是您在任何编程语言中都会使用的任何其他函数,但是存储的procs更像是单个程序或批处理脚本。
函数通常具有输出和可选的输入。然后可以将输出用作另一个函数(SQL Server内置的DATEDIFF,LEN等)的输入,或用作SQL Query的谓词-例如SELECT a, b, dbo.MyFunction(c) FROM table
或SELECT a, b, c FROM table WHERE a = dbo.MyFunc(c)
。
存储的proc用于在事务中将SQL查询绑定在一起,并与外界交互。诸如ADO.NET等框架无法直接调用函数,但是它们可以直接调用存储的proc。
但是,函数的确存在隐患:它们可能会被滥用并导致相当讨厌的性能问题:请考虑以下查询:
SELECT * FROM dbo.MyTable WHERE col1 = dbo.MyFunction(col2)
其中MyFunction声明为:
CREATE FUNCTION MyFunction (@someValue INTEGER) RETURNS INTEGER
AS
BEGIN
DECLARE @retval INTEGER
SELECT localValue
FROM dbo.localToNationalMapTable
WHERE nationalValue = @someValue
RETURN @retval
END
此处发生的是,对表MyTable中的每一行都调用了函数MyFunction。如果MyTable有1000行,那么这是针对数据库的另外1000个临时查询。同样,如果在列规范中指定时调用了该函数,则将为SELECT返回的每一行调用该函数。
因此,您确实需要谨慎编写函数。如果您从函数中的表中执行SELECT,则需要问自己:使用父存储过程中的JOIN还是其他一些SQL构造(例如CASE ... WHEN ... ELSE ...结束)。
SELECT * from dbo.MyTableValuedFunction()
。另一方面,通过将设置SqlCommand.CommandType
为,可以使用ADO.NET直接调用Sproc CommandType.StoredProcedure
。
存储过程和用户定义函数之间的区别:
RAISEERROR
OR @@ERROR
。GETDATE()
不能在UDF中使用。GETDATE()
可以在功能中使用。在枢不确定性是不是一个好。
STORE PROCEDURE FUNCTION (USER DEFINED FUNCTION)
* Procedure can return 0, single or | * Function can return only single value
multiple values. |
|
* Procedure can have input, output | * Function can have only input
parameters. | parameters.
|
* Procedure cannot be called from | * Functions can be called from
function. | procedure.
|
* Procedure allows select as well as | * Function allows only select statement
DML statement in it. | in it.
|
* Exception can be handled by | * Try-catch block cannot be used in a
try-catch block in a procedure. | function.
|
* We can go for transaction management| * We can't go for transaction
in procedure. | management in function.
|
* Procedure cannot be utilized in a | * Function can be embedded in a select
select statement | statement.
|
* Procedure can affect the state | * Function can not affect the state
of database means it can perform | of database means it can not
CRUD operation on database. | perform CRUD operation on
| database.
|
* Procedure can use temporary tables. | * Function can not use
| temporary tables.
|
* Procedure can alter the server | * Function can not alter the
environment parameters. | environment parameters.
|
* Procedure can use when we want | * Function can use when we want
instead is to group a possibly- | to compute and return a value
complex set of SQL statements. | for use in other SQL
| statements.
基本差异
函数必须返回一个值,但是在存储过程中它是可选的(过程可以返回零或n个值)。
函数只能具有输入参数,而过程可以具有输入/输出参数。
函数采用一个输入参数,这是强制性的,但存储过程可能采用o到n个输入参数。
可以从过程中调用函数,而不能从函数中调用过程。
提前差异
过程允许SELECT以及DML(INSERT / UPDATE / DELETE)语句,而Function则仅允许SELECT语句。
不能在SELECT语句中使用过程,而可以在SELECT语句中嵌入函数。
在WHERE / HAVING / SELECT部分的任何地方都不能在SQL语句中使用存储过程,而可以使用Function。
返回表的函数可以视为另一个行集。可以在与其他表的JOIN中使用。
内联函数可以作为带有参数的视图,并且可以在JOIN和其他Rowset操作中使用。
异常可以由Procedure中的try-catch块处理,而try-catch块不能在Function中使用。
我们可以在过程中进行事务管理,而不能在功能中进行事务管理。
Returns
关键字和必须是一个标量或表型) ,但存储过程可以有选择地返回:a)1 Int
种通过Return
语句的结果代码和/或b)1+ Cursor
通过Output
关键字的参数(包括类型)和/或c)1+通过Select
语句的行集(如果只有1个行集)返回,它可用作“插入到”语句的“ execute_statement”参数。”
存储过程:
EXEC
或EXECUTE
语句来调用。OUT
参数。功能:
只能用于选择记录。但是,可以从标准SQL中很容易地调用它,例如:
SELECT dbo.functionname('Parameter1')
要么
SELECT Name, dbo.Functionname('Parameter1') FROM sysObjects
对于简单的可重用选择操作,函数可以简化代码。只是要警惕JOIN
在函数中使用子句。如果您的函数有一个JOIN
子句,并且您从另一个返回多个结果的select语句中调用该子句,则该函数调用会将结果JOIN
表中返回的每一行这些表放在一起。因此,尽管它们有助于简化某些逻辑,但如果使用不当,它们也可能成为性能瓶颈。
OUT
参数返回值。用户定义的功能。
储存程序
SQL Server函数(例如游标)将用作最后的武器!它们确实存在性能问题,因此应尽可能避免使用表值函数。谈论性能是指一个表,该表在中型硬件的服务器上托管着超过1,000,000条记录。否则,您不必担心这些功能导致的性能下降。
有关更多参考,请参见:http : //databases.aspfaq.com/database/should-i-use-a-view-a-stored-procedure-or-a-user-defined-function.html
这是在存储过程中偏爱函数的实际原因。如果您的存储过程需要另一个存储过程的结果,则必须使用insert-exec语句。这意味着您必须创建一个临时表并使用一条exec
语句将存储过程的结果插入到临时表中。太乱了 一个问题是insert-execs不能嵌套。
如果您受困于调用其他存储过程的存储过程,则可能会遇到这种情况。如果嵌套存储过程只是返回一个数据集,则可以用表值函数替换它,您将不再遇到此错误。
(这是我们应该将业务逻辑保留在数据库之外的另一个原因)
函数可以用在select语句中,而过程则不能。
存储过程同时接受输入和输出参数,而功能仅接受输入参数。
函数无法在过程可以的地方返回text,ntext,image和timestamps类型的值。
函数可以在创建表中用作用户定义的数据类型,但过程不能。
***例如:-建立 table <tablename>(name varchar(10),salary getsal(name))
这里的getsal是一个用户定义的函数,它返回一个薪金类型,当创建表时,没有为薪金类型分配存储空间,也没有执行getsal函数。但是,当我们从该表中获取某些值时,getsal函数将被执行,并且return类型作为结果集返回。
我意识到这是一个非常老的问题,但是我没有看到任何答案中提到的一个关键方面:内联到查询计划中。
功能可以是...
标量:
CREATE FUNCTION ... RETURNS scalar_type AS BEGIN ... END
多语句表值:
CREATE FUNCTION ... RETURNS @r TABLE(...) AS BEGIN ... END
内联表值:
CREATE FUNCTION ... RETURNS TABLE AS RETURN SELECT ...
查询优化器将第三种类型(内联表值)本质上视为(参数化的)视图,这意味着从查询中引用该函数类似于复制粘贴该函数的SQL主体(实际上没有复制粘贴),导致有以下好处:
以上可能导致潜在的显着性能节省,尤其是在组合多个功能级别时。
注意:SQL Server 2019似乎也会引入某种形式的标量函数内联。
在SQL Server中,函数和存储过程是两种不同类型的实体。
功能:在SQL Server数据库中,这些功能用于执行某些操作,该操作会立即返回结果。函数有两种类型:
系统定义
用户自定义
存储过程:在SQL Server中,存储过程存储在服务器中,并且可以返回零,单个和多个值。存储过程有两种类型: