You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用存储过程通过OPENROWSET同步数据遇Msg7357权限/无列错误求助

咱们来搞定这个Msg 7357的错误,先理清楚问题根源,再给你几个靠谱的解决办法:

问题回顾

你原本的逻辑是传入当前数据库到存储过程,从临时表#clients_pom取数据做更新,但运行时碰到了这个错误:

Msg 7357, Level 16, State 2, Line 2 
无法处理对象"SET FMTONLY OFF; SET NOCOUNT ON; EXEC WBANKA_KBBL2.dbo.sp_kbbl_WachLista_Priprema '2017-09-30', '2017-09-30', 0"。链接服务器"(null)"对应的OLE DB提供程序"SQLNCLI"提示:该对象要么无列,要么当前用户无权限。

你的执行代码是这样的:

DECLARE @SQL VARCHAR(MAX)
DECLARE @Datum varchar(20)
SET @Datum= '2017-09-30'
IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti
SELECT @SQL = ' SELECT * INTO ##WL_Klijenti FROM OPENROWSET (''SQLOLEDB'',''Server= (local);TRUSTED_CONNECTION=YES;'',''SET FMTONLY OFF; SET NOCOUNT ON; EXEC ' + DB_NAME()+'.dbo.sp_kbbl_WachLista_Priprema ''''' + @Datum + ''''', ''''' + @Datum + ''''', 0'') AS tbl'
EXEC(@SQL)
UPDATE C SET C.watchListStatus = '1' FROM #clients_pom AS C INNER JOIN ##WL_Klijenti AS WL ON WL.mbr = C.registrationNumber
IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti

错误根源分析

我帮你拆解下这个问题的几个可能原因:

  • OPENROWSET的列检测机制坑:当用OPENROWSET调用存储过程时,SQL Server会先去探测存储过程返回的列结构。虽然你加了SET FMTONLY OFF,但这个设置可能没在正确的时机生效,导致SQL Server还是识别不到存储过程返回的列,于是抛出“无列”的错误。
  • 权限问题:执行这段代码的账户,可能没有足够权限去访问sp_kbbl_WachLista_Priprema存储过程,或者没法读取存储过程返回的结果集。
  • 多此一举的OPENROWSET:你连接的是本地服务器(local),完全没必要绕OPENROWSET,直接调用存储过程就行,这反而增加了复杂度和出错概率。

解决办法

方案1:直接调用存储过程(最推荐)

既然是本地环境,直接把存储过程的结果插入全局临时表就好,这是最简单最稳妥的方式:

DECLARE @Datum varchar(20)
SET @Datum= '2017-09-30'

IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti
-- 先手动创建全局临时表,列结构必须和存储过程返回的结果完全匹配
CREATE TABLE ##WL_Klijenti (
    mbr VARCHAR(50), -- 这里要替换成你存储过程实际返回的列名和类型
    -- 把存储过程返回的其他列都列在这里,比如:
    clientName VARCHAR(100),
    statusCode INT
    -- 其他列按需补充
)
-- 直接插入存储过程的执行结果
INSERT INTO ##WL_Klijenti
EXEC dbo.sp_kbbl_WachLista_Priprema @Datum, @Datum, 0

-- 执行你的更新逻辑
UPDATE C 
SET C.watchListStatus = '1' 
FROM #clients_pom AS C 
INNER JOIN ##WL_Klijenti AS WL ON WL.mbr = C.registrationNumber

-- 清理临时表
IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti

划重点:临时表的列结构必须和sp_kbbl_WachLista_Priprema返回的结果集完全一致,包括列名、数据类型和长度,不然插入会报错。

方案2:调整OPENROWSET语句,让FMTONLY生效

如果你因为某些原因一定要用OPENROWSET,可以试试把SET FMTONLY OFF的位置调整下,或者在远程语句里用变量传递参数,让SQL Server能正确识别列:

DECLARE @SQL VARCHAR(MAX)
DECLARE @Datum varchar(20)
SET @Datum= '2017-09-30'

IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti
SELECT @SQL = ' 
SELECT * INTO ##WL_Klijenti 
FROM OPENROWSET (''SQLOLEDB'',''Server= (local);TRUSTED_CONNECTION=YES;'',''
    SET NOCOUNT ON;
    SET FMTONLY OFF;
    -- 用变量传递参数,避免字符串拼接的问题
    DECLARE @dt1 VARCHAR(20) = ''''' + @Datum + ''''';
    DECLARE @dt2 VARCHAR(20) = ''''' + @Datum + ''''';
    EXEC ' + DB_NAME()+'.dbo.sp_kbbl_WachLista_Priprema @dt1, @dt2, 0
'') AS tbl'
EXEC(@SQL)

UPDATE C 
SET C.watchListStatus = '1' 
FROM #clients_pom AS C 
INNER JOIN ##WL_Klijenti AS WL ON WL.mbr = C.registrationNumber

IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti

另外,要确保执行这段代码的账户对sp_kbbl_WachLista_Priprema有EXECUTE权限,同时能访问存储过程用到的所有底层表。

方案3:用EXEC AT替代OPENROWSET

如果必须用分布式查询的方式,可以用EXEC AT来调用存储过程并插入临时表:

DECLARE @Datum varchar(20)
SET @Datum= '2017-09-30'

IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti
-- 同样要先创建匹配列结构的临时表
CREATE TABLE ##WL_Klijenti (
    mbr VARCHAR(50),
    -- 其他列...
)

DECLARE @ExecSQL NVARCHAR(MAX) = N'
INSERT INTO ##WL_Klijenti
EXEC ' + QUOTENAME(DB_NAME()) + N'.dbo.sp_kbbl_WachLista_Priprema @dt, @dt, 0'

-- 用sp_executesql传递参数,避免注入风险
EXEC sp_executesql @ExecSQL, N'@dt VARCHAR(20)', @dt = @Datum

UPDATE C 
SET C.watchListStatus = '1' 
FROM #clients_pom AS C 
INNER JOIN ##WL_Klijenti AS WL ON WL.mbr = C.registrationNumber

IF OBJECT_ID('tempdb..##WL_Klijenti') IS NOT NULL DROP TABLE ##WL_Klijenti

总结

最推荐方案1,本地环境下直接调用存储过程是最简洁、最不容易出问题的方式,完全避开了分布式查询带来的权限和列检测坑。如果一定要用OPENROWSET,记得把SET FMTONLY OFF的位置调整好,同时确保账户权限足够。

内容的提问来源于stack exchange,提问作者unknown

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:47:11