首页 新闻 会员 周边 捐助

mybatis 调用存储过程出现错误TransientDataAccessResourceException:不允许使用远程表值函数调用

-1
悬赏园豆:5 [已关闭问题] 关闭于 2015-09-02 15:10

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

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
提问于:2015-08-08 17:50
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册