none
【SQL】有关函数内部能用哪些东西的问题? RRS feed

  • 问题

  • SQL 2008。

    已知函数内部不能用sp_executesql,不能用EXEC执行动态语句,请问函数内部能使用哪些存储过程?

    2012年9月7日 4:53

答案

  • 语法上有写

    http://msdn.microsoft.com/zh-cn/library/ms186755.aspx

    下列语句在函数内有效:

    • 赋值语句。

    • TRY...CATCH 语句以外的流控制语句。

    • 定义局部数据变量和局部游标的 DECLARE 语句。

    • SELECT 语句,其中的选择列表包含为局部变量分配值的表达式。

    • 游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。 只允许使用以 INTO 子句向局部变量赋值的 FETCH 语句;不允许使用将数据返回到客户端的 FETCH 语句。

    • 修改本地表变量的 INSERT、UPDATE 和 DELETE 语句。

    • 调用扩展存储过程的 EXECUTE 语句。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:35
    2012年9月7日 5:24
  • 扩展存储过程是 SQL Server 实例可以动态加载和运行的 DLL。扩展存储过程是使用 SQL Server 扩展存储过程 API 编写的,可直接在 SQL Server 实例的地址空间中运行。

    你可以通过执行存储过程 sp_helpextendedproc 得到扩展存储过程列表

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月7日 6:43
  • 以前以为 以xp开头的存储过程是扩展存储过程,感谢邹建大侠

    给我写信: QQ我:点击这里给我发消息


    这是通常建议的命名规则,不是强制性的。

    想不想时已是想,不如不想都不想。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月7日 12:55
    版主
  • 你好,

    在函数中调用sp_executesql是不被允许的。如果可以的话,可以试着把函数转为存储过程,这样的话,就可以使用sp_executesql了。

    Thanks.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help. This can be beneficial to other community members reading the thread.

    2012年9月10日 8:42
    版主
  • 谢谢建议,这是个硬伤,总有存储过程不能代替函数的时候。

    我想知道到底哪些存储过程可以用作函数中?因为“调用扩展存储过程的 EXECUTE 语句”这句话已经不可靠了,有没有个清单之内?

    你可能没有注意到,联机丛书除了说可以调用扩展存储过程以外,下面还详细的说明了这一部分:

    从函数中调用扩展存储过程

    <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">

    如果在函数中调用扩展存储过程,则该过程不能向客户端返回结果集。向客户端返回结果集的任何 ODS API 都将返回
    FAIL。扩展存储过程可以连接回 SQL Server 的实例;不过,该过程不应尝试与调用扩展存储过程的函数同时联接到同一事务。

    与通过批处理或存储过程进行调用相似,扩展存储过程在运行 SQL Server 的 Windows
    安全帐户的上下文中执行。存储过程的所有者在授予用户 EXECUTE 权限时应考虑这一点。

    sp_executesql是会返回结果集的,所以不能使用,执行函数时会告诉你,消息 557,级别 16,状态 2,第 1 行
    只有函数和某些扩展存储过程才能从函数内部执行。

    </content>

    想不想时已是想,不如不想都不想。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月14日 7:25
    版主

全部回复

  • 语法上有写

    http://msdn.microsoft.com/zh-cn/library/ms186755.aspx

    下列语句在函数内有效:

    • 赋值语句。

    • TRY...CATCH 语句以外的流控制语句。

    • 定义局部数据变量和局部游标的 DECLARE 语句。

    • SELECT 语句,其中的选择列表包含为局部变量分配值的表达式。

    • 游标操作,该操作引用在函数中声明、打开、关闭和释放的局部游标。 只允许使用以 INTO 子句向局部变量赋值的 FETCH 语句;不允许使用将数据返回到客户端的 FETCH 语句。

    • 修改本地表变量的 INSERT、UPDATE 和 DELETE 语句。

    • 调用扩展存储过程的 EXECUTE 语句。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:35
    2012年9月7日 5:24
  • 谢谢,再请问如何知道一个存储过程是否扩展存储过程?sp_executesql算么?

    2012年9月7日 5:37
  • 扩展存储过程是 SQL Server 实例可以动态加载和运行的 DLL。扩展存储过程是使用 SQL Server 扩展存储过程 API 编写的,可直接在 SQL Server 实例的地址空间中运行。

    你可以通过执行存储过程 sp_helpextendedproc 得到扩展存储过程列表

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月7日 6:43
  • 以前以为 以xp开头的存储过程是扩展存储过程,感谢邹建大侠

    给我写信: QQ我:点击这里给我发消息

    2012年9月7日 10:40
  • 非常感谢邹大,以你的经验,有没有办法在函数中执行动态语句并获得执行的返回或结果集?
    2012年9月7日 11:13
  • 以前以为 以xp开头的存储过程是扩展存储过程,感谢邹建大侠

    给我写信: QQ我:点击这里给我发消息


    这是通常建议的命名规则,不是强制性的。

    想不想时已是想,不如不想都不想。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月7日 12:55
    版主
  • 根据sp_helpextendedproc所示,sp_executesql赫然在列,可为什么就不让在函数中调用呢?
    2012年9月8日 4:39
  • 你好,

    在函数中调用sp_executesql是不被允许的。如果可以的话,可以试着把函数转为存储过程,这样的话,就可以使用sp_executesql了。

    Thanks.


    Please remember to mark the replies as answers if they help and unmark them if they provide no help. This can be beneficial to other community members reading the thread.

    2012年9月10日 8:42
    版主
  • 谢谢建议,这是个硬伤,总有存储过程不能代替函数的时候。

    我想知道到底哪些存储过程可以用作函数中?因为“调用扩展存储过程的 EXECUTE 语句”这句话已经不可靠了,有没有个清单之内?

    2012年9月14日 4:58
  • 谢谢建议,这是个硬伤,总有存储过程不能代替函数的时候。

    我想知道到底哪些存储过程可以用作函数中?因为“调用扩展存储过程的 EXECUTE 语句”这句话已经不可靠了,有没有个清单之内?

    你可能没有注意到,联机丛书除了说可以调用扩展存储过程以外,下面还详细的说明了这一部分:

    从函数中调用扩展存储过程

    <content xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5">

    如果在函数中调用扩展存储过程,则该过程不能向客户端返回结果集。向客户端返回结果集的任何 ODS API 都将返回
    FAIL。扩展存储过程可以连接回 SQL Server 的实例;不过,该过程不应尝试与调用扩展存储过程的函数同时联接到同一事务。

    与通过批处理或存储过程进行调用相似,扩展存储过程在运行 SQL Server 的 Windows
    安全帐户的上下文中执行。存储过程的所有者在授予用户 EXECUTE 权限时应考虑这一点。

    sp_executesql是会返回结果集的,所以不能使用,执行函数时会告诉你,消息 557,级别 16,状态 2,第 1 行
    只有函数和某些扩展存储过程才能从函数内部执行。

    </content>

    想不想时已是想,不如不想都不想。

    • 已标记为答案 ahdung_AI 2012年9月19日 15:36
    2012年9月14日 7:25
    版主
  • 估计LZ跟我一样很少看联机丛书


    给我写信: QQ我:点击这里给我发消息

    2012年9月15日 9:47
  • 非常感谢怡红公子解惑~我有看官方文档这习惯的,而且是作为了解一个东西的首选途径。但往往官方的文档都是大而全的,动不动就是一大篇,像create database,若干选项,往往多数时候都是目的明确的去了解一个应用点,所以不太耐烦从头看到尾,是可能忽略一些重要但视觉上又没强调的段落

    2012年9月19日 15:15
  • 非常感谢怡红公子解惑~我有看官方文档这习惯的,而且是作为了解一个东西的首选途径。但往往官方的文档都是大而全的,动不动就是一大篇,像create database,若干选项,往往多数时候都是目的明确的去了解一个应用点,所以不太耐烦从头看到尾,是可能忽略一些重要但视觉上又没强调的段落

    同意。一般不是dba的话,没有谁没事去翻BOL看着玩的。这一段我也没有仔细看过。但是你在遇到问题的时候,就应该把文档仔细看一看,而不是直接就奔论坛或者google。

    桦仔,你也应该养成遇到问题先查文档的习惯。


    想不想时已是想,不如不想都不想。

    2012年9月21日 14:59
    版主
  • 有时候bol大而全,我一般都是先找度娘


    给我写信: QQ我:点击这里给我发消息

    2012年9月21日 16:06
  • 是的,再次感谢!
    2012年9月23日 2:12