调用表值函数时使用 NOLOCK 提示

Jer*_*oen 8 sql-server sql-server-2012 functions nolock

假设有以下函数:

CREATE FUNCTION [dbo].[ufnTest]()
RETURNS TABLE
AS RETURN SELECT 1 AS Nr
Run Code Online (Sandbox Code Playgroud)

我的实际函数将从许多不同的表中选择实际数据。我(大部分)理解使用 nolock 提示的风险,并决定在这种情况下我真的想要它们。所以我尝试像这样调用上面的函数:

SELECT * FROM [dbo].[ufnTest]() WITH(NOLOCK)
Run Code Online (Sandbox Code Playgroud)

但是,这失败并显示以下消息:

关键字“with”附近的语法不正确。如果此语句是公共表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前一条语句必须以分号终止。

修复此错误的提示不相关。也许这个表提示不适用于表值函数?

我会考虑几种选择。一种是在我的选择查询中的所有表上使用提示,但我不想这样做,因为 (a) 每当我更改函数时我都必须记住这一点,并且 (b) 它是重复的。另一种选择是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED,但缺点是我不太知道如何将它设置回之前的状态(并且从我的 TVF 选择之后的语句应该具有原始隔离级别)。

因此,我更愿意WITH (NOLOCK)从表值函数中进行选择。这可能吗?

Mar*_*son 10

您不能WITH (NOLOCK)在表值函数上使用 a ,除非您将它放在函数内代码中的每个表上。

就像你说的,你最好的选择是SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

要将其改回默认值,您需要找出当前设置的隔离级别(在上面更改之前)。

这可以通过运行DBCC USEROPTIONS并检查 的值来完成isolation level

默认值往往是READ COMMITTED,因此要将其更改为该值,您需要编写如下语句:

SET TRANSACTION ISOLATION LEVEL READ COMMITTED