我有一个表值函数
ALTER FUNCTION dbo.fn_Test
()
RETURNS
@t TABLE
(
ID INT
)
AS
BEGIN
INSERT INTO @t(ID) select ID from dbo.Table;
RETURN
END
GO
我的问题是,如果我在连接到另一个表的 select 语句中使用此函数,主查询 aqcuire 是否会共享 dbo.Table 上的读锁?或者它会从主查询中独立获取锁来填充表变量吗?
谢谢
最佳答案
至少在 SQL Server 2019 中提交读时,一旦填充表变量,锁就会被释放。
我可以在 Profiler 中看到这一点(绿色是表的对象 ID,黄色是函数的对象 ID)
我不能 100% 确定我没有错过任何内容,因此我尝试了以下设置...
CREATE TABLE dbo.T1(ID int primary key)
CREATE TABLE dbo.T2(ID int primary key)
INSERT dbo.T1 VALUES (1),(2),(3),(4),(5)
INSERT dbo.T2 VALUES (1),(2),(3),(4),(5)
GO
CREATE FUNCTION dbo.fn_Test()
RETURNS @t TABLE ( ID INT)
AS
BEGIN
INSERT INTO @t(ID) select ID from dbo.T1;
RETURN
END
GO
我能够开始以下查询(返回 1,953,125 行,并且对我来说至少需要 10 秒)
SELECT *
FROM dbo.T2 a
CROSS JOIN dbo.T2 b
CROSS JOIN dbo.T2 c
CROSS JOIN dbo.T2 d
CROSS JOIN dbo.T2 e
CROSS JOIN dbo.T2 f
CROSS JOIN dbo.T2 g
CROSS JOIN dbo.T2 h
CROSS JOIN dbo.T2 i
JOIN dbo.fn_Test() fn ON fn.ID = a.ID
然后立即转到另一个窗口并运行
drop table dbo.T1
成功且没有被阻止,并且结果仍在另一个连接中传输
关于sql-server - SQL Server表值函数锁问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75700450/