为什么我们不能在函数内部执行存储过程,而相反的情况是可能的?
8 回答
您不能在函数内部执行存储过程,因为不允许函数修改数据库状态,并且允许存储过程修改数据库状态。
这是根据定义(参见CREATE FUNCTION - Limitations and Restrictions)。
用户定义的函数不能用于执行修改数据库状态的操作。
存储过程可能会修改数据库状态,也可能不会。但是 SQL Server 编译器不必分析存储过程就可以知道它是否修改了数据库状态。因此,不允许在函数内执行存储过程。
函数的存在只是为了简单地计算一些东西、一个值或一个表结果,仅此而已。例如,可以在SELECT
查询中调用这些函数,例如
SELECT calculate_something(a) FROM some_table;
现在考虑如果calculate_something
允许该函数执行一个存储过程,该存储过程将删除some_table
. 你的意图是使用列的值来计算一些东西some_table.a
,但你最终......删除了some_table
. 这显然不是你想要发生的事情。
我知道这已经得到了回答,但是在 SQL Server 中,该功能不应该更改数据,而是该过程的目的。
除此之外,我想补充一点,我们不能选择过程或将其放在 where 子句中,但我们可以使用函数来做到这一点。
我们使用函数来缩短代码,因此它非常有用,因为它减少了编码器的大量查询。
希望这可以帮助。
我们不能在函数中调用存储过程。但是,我们可以在存储过程中调用函数。
功能极其有限。他们不能以任何可以更改数据的方式执行任何操作。这意味着您不能使用动态sql或调用其他对象(函数除外)
我怀疑这是因为函数的执行不应该以任何方式修改数据,并且允许您运行存储过程会让您这样做......
您需要将存储过程更改为函数才能从函数中调用它。
或者,一种方法是使用xp_cmdshell
调用批处理文件,其中批处理文件包含执行过程语句。在函数中,您可以调用扩展过程。
例如。
Create Function...
EXEC master.sys.xp_cmdshell 'C:\test.bat'
RETURN...
我绝不是说这是一种好的做法,我只是说这是一种可能性。
一些限制是他们的功能,比如(i)它不应该改变任何表结构。它应该是只读表。但是存储过程可以改变。存储过程可以做任何改变。所以我们不能从函数中调用存储过程。
我们可以在函数内部调用过程,但不能通过select语句调用该函数。如果通过另一个调用程序调用该函数,则该函数可以正常工作。dml操作也是如此。函数可以有dml操作,但不能通过select语句调用.而如果您通过另一个程序调用该函数,则会执行 dml
从技术上讲,从函数调用存储过程是可能的。但请记住存储过程和函数的用途。
函数的目的:函数用于计算一个值,因此必须返回一个值。只要不改变数据,就可以从 select 语句中调用函数。(永久表数据,不是临时表)
存储过程的目的:存储过程用于执行业务逻辑,因此可能返回值,也可能不返回值。