GQ2010
gq2010
采纳率14.3%
2015-08-11 00:18

调用存储过程出错,提示不允许使用远程表值函数调用

5

1、项目使用springmvc, spring, mybatis三个框架
2、在一个serverice中调用dao的方法,dao方法执行的是一个存储过程,该service方法在spring的事务中进行了如下配置,不使用事务管理。

3、数据库使用SQL Server 2008

现在service在执行refreshMetaData,出现了如下问题:

图片说明

而在数据库中直接执行这个存储过程就不会出现任何错误信息,正常执行。存储过程中使用了SQL Server的链接服务器linkedserver。

存储过程代码如下:

1 CREATE PROC [dbo].[PRO_UPDATE_METADATA]
2 @metadataclassId int,
3 @parentmetadataclassId int,
4 @metadataTabName varchar(500),
5 @linkedServerName varchar(8000),
6 @planDBHost varchar(20),
7 @planDBName varchar(200),
8 @planDBUser varchar(200),
9 @planDBPWD varchar(200),
10 @planDBPort varchar(10),
11 @trans INT output

12 AS
13 DECLARE @remoteServer varchar(8000) =''; -- 远程服务器地址

14 DECLARE @TableName varchar(8000) =''; -- 代码表名称
15 DECLARE @TableNames varchar(8000) =''; -- 所有代码表名称组成的字符串
16 DECLARE @fieldName varchar(8000) ='';-- 元数据字段名称
17 DECLARE @fieldNames varchar(8000) ='';-- 元数据所有字段名称组成的字符串
18 DECLARE @fieldNamesWithTempTable varchar(8000) ='';-- 元数据所有字段名称组成的字符串
19 DECLARE @readFieldsSQL varchar(8000) = ''; -- 需要读取的字段
20 DECLARE @readFieldsSQL2 varchar(8000) = ''; -- 需要读取的字段
21 DECLARE @inserDataSql varchar(8000) ='';-- 存储元数据的SQL
22

23 DECLARE @result_flag int = 0; -- 出错标识,用户事物回滚提交
24

25 DECLARE @count int;
26 DECLARE fieldsCur CURSOR FOR select CODE_TABLE, FIELD_NAME from TBL_METADATA_CLASS_FIELD where
27 METADATA_ID=@metadataclassId or METADATA_ID=@parentmetadataclassId; -- 元数据字段
28

29

30 DECLARE @dataTblName varchar(200);-- 包含元数据属性的数据表名称
31 DECLARE @getCodeTableDataSQL varchar(8000);-- 获取代码表数据的SQL
32 DECLARE @getDataTableSQL varchar(8000); -- 获取数据表数据的SQL
33 DECLARE @unitFiles varchar(8000); -- 获取被审计单位信息
34 DECLARE @joinConditions varchar(8000); -- -数据表于代码表查询数据的条件
35 DECLARE @tableCursorSQL nvarchar(max); -- 动态创建游标SQL
36

37 BEGIN
38

39 /*创建链接服务器*/
40 set @remoteServer = @planDBHost + ',' + @planDBPort
41 -- 判断链接服务器是否存在
42 IF EXISTS (SELECT 1 FROM MASTER..SYSSERVERS WHERE SRVNAME = @linkedServerName)
43 EXEC SP_DROPSERVER @linkedServerName,'DROPLOGINS'
44 -- 创建链接服务器
45 EXEC sp_addlinkedserver
46 @server=@linkedServerName,
47 @srvproduct='',
48 @provider='SQLOLEDB',
49 @datasrc=@remoteServer;
50

51 -- 登录链接服务器
52 EXEC sp_addlinkedsrvlogin @linkedServerName, 'false', NULL, @planDBUser, @planDBPWD
53

54 BEGIN TRANSACTION;
55

56 /*获取元数据字段信息*/

57 set @count = 0;
58 set @joinConditions = ' 1=1 '
59 Open fieldsCur;
60 fetch next from fieldsCur Into @TableName,@fieldName
61 While ( @@Fetch_Status=0 )
62 begin
63 DECLARE @tableAlias varchar(30);
64 set @tableAlias = 'data_tab_' + CONVERT(varchar(2), @count);
65 set @readFieldsSQL = @readFieldsSQL + ', ' + '[' + @tableAlias + '].[' + @fieldName + '] as [' + @fieldName + ']';
66 set @readFieldsSQL2 = @readFieldsSQL2 + ', ' + '[#dataTblName#].[' + @fieldName + '] as [' + @fieldName + ']';
67 set @fieldNames = @fieldNames + ', ' + '[' + @fieldName + ']';
68 set @fieldNamesWithTempTable = @fieldNamesWithTempTable + ', ' + '#codetabledata.[' + @fieldName + ']';
69 set @TableNames = @TableNames + ',[' + @linkedServerName + '].[' + @planDBName + '].[dbo].' + '[' + @TableName + '] ' + @tableAlias;
70 set @joinConditions = @joinConditions + ' and [#dataTblName#].[' + @fieldName + ']=#codetabledata.[' + @fieldName + ']';
71 set @count = @count + 1;
72 fetch next from fieldsCur Into @TableName,@fieldName;
73 end
74 Close fieldsCur;
75 Deallocate fieldsCur;
76

77 IF @@ERROR<>0
78 SET @result_flag=1;
79

80 -- 找出包含元数据分类属性的表
81 set @tableCursorSQL = 'DECLARE tablesCur CURSOR FOR select tblName from ( ' +
82 'select ' +
83 'sysobjects.name as tblName, ' +
84 'COUNT(*) as colCount ' +
85 'from ' + @linkedServerName + '.' + @planDBName + '.dbo.sysobjects ' +
86 'left join ' +
87 @linkedServerName + '.' + @planDBName + '.dbo.syscolumns ' +
88 'on sysobjects.id = syscolumns.id ' +
89 'where ' +
90 'sysobjects.xtype=''U'' ' +
91 'and syscolumns.name in ( ' +
92 'select FIELD_NAME from TBL_METADATA_CLASS_FIELD ' +
93 'where METADATA_ID=' + convert(varchar(20), @metadataclassId) + ' or METADATA_ID= ' + convert(varchar(20), @parentmetadataclassId) +
94 ') ' +
95 'group by sysobjects.name ' +
96 ') as cc where colCount >=' + convert(varchar(20), @count) + ' and tblName not like ''代码表_%''';
97

98 exec sp_executesql @tableCursorSQL;
99

100 IF @@ERROR<>0
101 SET @result_flag=1

102

103 -- 清空数据信息表
104 exec ('truncate table ' + @metadataTabName);
105 open tablesCur;
106 fetch next from tablesCur Into @dataTblName
107 While ( @@Fetch_Status=0 )
108 begin
109 -- 获取代码表数据
110 set @getCodeTableDataSQL = 'select distinct ' + SUBSTRING(@readFieldsSQL, 2, LEN(@readFieldsSQL)-1) + ' into #codetabledata from ' + SUBSTRING(@TableNames, 2, LEN(@TableNames)-1);
111

112 -- 基本单位信息
113 set @unitFiles = ',TBL_UNDERAUDITUNIT.[underauditunit] as [被采集单位信息], TBL_UNDERAUDITUNIT.[datadesc] as [数据信息描述], ' +
114 'TBL_UNDERAUDITUNIT.[othersoft] as [对方软件信息], TBL_UNDERAUDITUNIT.[remark] as [备注] ';
115

116 set @getDataTableSQL = 'select [col_id] as [DC_ID], [unit_id] ' + @unitFiles + REPLACE(@readFieldsSQL2, '#dataTblName#', @dataTblName) + ' into #metatableadata from #codetabledata ' +
117 'left join ' +
118 @linkedServerName + '.' + @planDBName + '.dbo.' + @dataTblName + ' ' +
119 'on ' +

120 REPLACE(@joinConditions, '#dataTblName#', @dataTblName) + ' ' +
121 'left join TBL_UNDERAUDITUNIT ' +
122 'on ' +
123 'TBL_UNDERAUDITUNIT.id = ' + @dataTblName + '.unit_id where col_id is not null';
124

125

126 set @inserDataSql = ' insert into ' + @metadataTabName + '([DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ') select * from ( ' +
127 ' select [DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ' from #metatableadata ' +
128 ' except ' +
129 ' select [DC_ID],[被采集单位信息], [数据信息描述],[对方软件信息],[备注] ' + @fieldNames + ' from ' + @metadataTabName +
130 ' ) as metatab ';
131

132

133 exec(@getCodeTableDataSQL + ';' + @getDataTableSQL + ';' + @inserDataSql + '; drop table #codetabledata; drop table #metatableadata;');
134

135
136 fetch next from tablesCur Into @dataTblName
137 end
138 Close tablesCur;
139 Deallocate tablesCur;
140

141 IF @result_flag=1
142 BEGIN
143 ROLLBACK TRANSACTION
144 SET @trans=1
145 END
146 ELSE
147 BEGIN
148 COMMIT TRANSACTION
149 SET @trans =0
150 END
151 -- 退出登录
152 Exec sp_droplinkedsrvlogin @linkedServerName, null;
153 --删除链接服务器
154 Exec sp_dropserver @linkedServerName;
155 select @trans as trans

156

157 END

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • GQ2010 gq2010 6年前

    程序调用存储过程,与在数据库中执行存储过程,使用的都是sa用户

    点赞 评论 复制链接分享
  • u010025966 进无止 6年前

    看看你请求数据库的用户权限是不是够。

    点赞 评论 复制链接分享

为你推荐