从Varchar列提取特定值并拆分为行:执行代码遇Msg2809报错求助
解决Msg 2809错误:表值函数不能用
EXEC执行的问题 问题还原
你遇到的错误提示:
Msg 2809:请求的过程'SplitStringTest'失败,因为'SplitStringTest'是表值函数对象。
对应的代码片段:
DECLARE @ID INT DECLARE @Name VARCHAR(MAX) DECLARE @opt VARCHAR(MAX) DECLARE CursorTest CURSOR FOR SELECT ID, Name, dbo.RemoveCharacterswithoutspacesTest(Desc) as opt FROM input_table OPEN CursorTest FETCH NEXT FROM CursorTest INTO @ID,@Name, @opt WHILE @@FETCH_STATUS = 0 BEGIN EXEC SplitStringTest @opt FETCH NEXT FROM CursorTest INTO @ID,@Name, @opt END CLOSE CursorTest DEALLOCATE CursorTest
问题根源
核心问题很简单:你用EXEC(执行存储过程的命令)去调用表值函数了。SQL Server里,表值函数和存储过程的调用规则完全不同,EXEC只认存储过程或动态SQL,不认表值函数。
解决办法
根据你的需求,有两种直接可行的修改方式:
1. 直接查询表值函数结果
把游标里的EXEC SplitStringTest @opt替换成SELECT语句,这样就能正确获取拆分后的结果:
-- 直接输出拆分结果 SELECT * FROM dbo.SplitStringTest(@opt) -- 如果需要关联当前游标里的ID和Name,这么写 SELECT @ID AS 原表ID, @Name AS 原表名称, 拆分结果.* FROM dbo.SplitStringTest(@opt) 拆分结果
2. 将拆分结果插入到目标表
如果要把拆分后的数据保存到某个表中,用INSERT INTO ... SELECT的组合:
INSERT INTO 你的目标表(原表ID, 原表名称, 拆分后的值) SELECT @ID, @Name, 拆分结果.* FROM dbo.SplitStringTest(@opt) 拆分结果
额外优化:抛弃游标,用集合操作提升性能
游标在SQL里效率通常不高,如果你的业务逻辑允许,完全可以用CROSS APPLY替代游标,一次性处理所有行,代码更简洁还更快:
SELECT t.ID AS 原表ID, t.Name AS 原表名称, s.* FROM input_table t CROSS APPLY dbo.SplitStringTest(dbo.RemoveCharacterswithoutspacesTest(t.[Desc])) s
内容的提问来源于stack exchange,提问作者user7427808
相关产品推荐
相关产品推荐

