存储过程使用表变量或临时表代替游标Fetch实例,访问远程数据库
定义表变量是可以直接操作在内存中的数据,比较快。临时表在大数据量时会比游标使用的资源少。还是要看具体情况了。也有可能在实际优化过程中相互替换呢。
留作记忆的代码如下:
if object_id('tempdb..#Tmp') is not null
Begin
drop table #Tmp
End
create table #Tmp --创建临时表#Tmp为获取远程设备信息使用
(
deviceId varchar(50),
deviceNo varchar(200),
FlagID TINYINT
);
declare @i int,--执行一条sql语句的临时变量,用于远程数据库配置信息循环
@j int,--执行一条sql语句的临时变量,用于更新设备信息名称
@user varchar(50),--用户名
@password varchar(100),--密码
@ssid varchar(100),--ssid
@db varchar(100),--数据库名称
@server varchar(100),--远程数据库server
@database varchar(200),
@remoteid int
--定义远程数据库配置信息临时表
declare @tRemoteOffice table
(
RemoteId int,
RomoteUser varchar(50),
RemotePassword varchar(100),
RemoteSsid varchar(100),
RemoteDb varchar(100),
RemoteName varchar(100),
FlagID TINYINT
)
begin
BEGIN TRY---------------------开始捕捉异常
--1.查询远程数据库配置表,插入查询数据到临时表
insert @tRemoteOffice select remote_id, remote_user,remote_psw,remote_ssid,remote_database,remote_name,0 from dbo.RemoteDBInfo;
print CONVERT(varchar(100), GETDATE(),21)+'插入远程数据库配置信息到临时表,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
set @i=1;
--Return_connectError:
while(@i>=1)
begin
Return_begin:
--2.选取临时表里的一条数据
SELECT TOP 1 @remoteid=RemoteId, @user = RomoteUser,@password=RemotePassword,@ssid=RemoteSsid,@db=RemoteDb,@server=RemoteName FROM @tRemoteOffice WHERE FlagID=0;
SET @i=@@ROWCOUNT
IF @i<=0 GOTO Return_Lab
print '开始连接远程数据库,ssid:'+@ssid;
begin try
--3.连接远程数据库
exec sp_addlinkedserver @server, ' ', 'SQLOLEDB', @ssid ;
exec sp_addlinkedsrvlogin @server, 'false ',null, @user, @password ;
select @database=@server+'.'+@db;
--4.查询远程数据库的机构信息
declare @officeID nvarchar(50),
@officeName nvarchar(200)
declare @searchRemoteOfficeSql Nvarchar(max)=N'SELECT @Id=office_id,@Name=office_name FROM '+@database+'.dbo.Office where caste=0';
Exec sp_executesql @searchRemoteOfficeSql,N'@Id nvarchar(50) output,@Name nvarchar(100) output',@officeID output,@officeName output;
print CONVERT(varchar(100), GETDATE(),21)+'查询远程数据库机构信息,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
update dbo.RemoteDBInfo set remote_type=1 WHERE remote_ssid = @ssid ;
end try
begin catch
print '连接远程数据库'+@ssid+'异常'
exec sp_dropserver @server, 'droplogins ';
UPDATE @tRemoteOffice SET FlagID=1 WHERE RemoteSsid = @ssid;
update dbo.RemoteDBInfo set remote_type=0 WHERE remote_ssid = @ssid ;
goto Return_begin
end catch
--5.查询已连接的远程数据库officeid是否已在本地表中
declare @SearchLocalUnitySql Nvarchar(max)=N'select UnityId from dbo.Unity where UnityId =@Id ';
Exec sp_executesql @SearchLocalUnitySql,N'@Id nvarchar(50)',@Id=@officeID;
--6.不在本地表中,插入新的机构信息
if @@ROWCOUNT=0
begin
declare @InsertUnityOfficeSql Nvarchar(max)=N'insert into dbo.Unity (UnityId,Name,ParentId,Type,remote_id) values(@id,@name,NULL,0,@remote_id) ';
Exec sp_executesql @InsertUnityOfficeSql,N'@id nvarchar(50),@name nvarchar(200),@remote_id int',@id=@officeID,@name=@officeName,@remote_id=@remoteid;
print CONVERT(varchar(100), GETDATE(),21)+'插入新的机构信息,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
end
--7.在本地表中,更新机构名称
else
begin
declare @UpdateUnityOfficeNameSql Nvarchar(max)=N'update dbo.Unity set Name=@Name1,remote_id=@remote_id where UnityId=@Id1 ';
Exec sp_executesql @UpdateUnityOfficeNameSql,N'@Name1 nvarchar(100),@Id1 nvarchar(50),@remote_id int',@Name1=@officeName,@Id1=@officeID,@remote_id=@remoteid;
print CONVERT(varchar(100), GETDATE(),21)+'更新机构信息,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
end
--8.插入设备信息到临时表
truncate table #Tmp
declare @deviceID varchar(50),
@deviceName varchar(200)
declare @InsertRemoteDeviceSql Nvarchar(max)=N'insert #Tmp select device_id,device_no,0 FROM '+@server+'.'+@db+'.dbo.device where parent_id is null and is_bom=0 and status=1 ';
Exec sp_executesql @InsertRemoteDeviceSql;
print CONVERT(varchar(100), GETDATE(),21)+'插入设备信息到临时表,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
set @j=1;
while(@j>=1)
begin
--9.选取临时表里的一条数据
SELECT TOP 1 @deviceID = deviceId,@deviceName=deviceNo FROM #Tmp WHERE FlagID=0;
SET @j=@@ROWCOUNT
IF @j<=0 GOTO Return_device
--10.查询临时表里的deviceId是否在Unity里
declare @SearchLocalUnityDeviceSql Nvarchar(max)=N'select UnityId from dbo.Unity where UnityId =@id ';
Exec sp_executesql @SearchLocalUnityDeviceSql,N'@id nvarchar(50)',@id=@deviceID;
--@@ROWCOUNT被执行一次后清零
--print CONVERT(varchar(100), GETDATE(),21)+'查询临时表里的设备id是否在Unity里,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
--11.不在表数据里,插入新的设备信息
if @@ROWCOUNT=0
begin
declare @InsertUnityDeviceSql Nvarchar(max)=N'insert into dbo.Unity (UnityId,Name,ParentId,Type) values (@id,@name,@parentid,1) ';
Exec sp_executesql @InsertUnityDeviceSql,N'@id nvarchar(50),@name nvarchar(200),@parentid nvarchar(50)',@id=@deviceID,@name=@deviceName,@parentid=@officeID;
print CONVERT(varchar(100), GETDATE(),21)+'插入新的设备信息,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
end
--12.在表数据里,更新设备名称
else
begin
declare @UpdateUnityDeviceNameSql Nvarchar(max)=N'update dbo.Unity set Name=@name where UnityId=@id ';
Exec sp_executesql @UpdateUnityDeviceNameSql,N'@name nvarchar(200),@id nvarchar(50)',@name=@deviceName,@id=@deviceID;
print CONVERT(varchar(100), GETDATE(),21)+'更新设备名称,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
end
--13.获取本地FireReport表的最新数据时间
declare @fireReportTime DateTime
declare @SearchFireReportTime Nvarchar(max)=N'SELECT top 1 @time=FindTime FROM dbo.FireReport where UnityId=@id order by FindTime desc';
Exec sp_executesql @SearchFireReportTime,N'@time Datetime output,@id nvarchar(50)',@fireReportTime output,@id=@deviceID;
--14.插入火情信息数据
if @fireReportTime=null
begin
set @fireReportTime=GETDATE();
end
--0 未处理,1确认,2误报,3取消,4上报,5未知状态
declare @InsertFireSql Nvarchar(max)=N'insert into dbo.FireReport(FindTime,FireType,UnityId)
select raised_dt
,CASE WHEN confirmed = 0 and cancelled=0 and discarded=0 and reported=0 THEN 0
WHEN confirmed = 1 and cancelled=0 and discarded=0 and reported=0 THEN 1
WHEN confirmed = 0 and cancelled=0 and discarded=1 and reported=0 THEN 2
WHEN confirmed = 0 and cancelled=3 and discarded=0 and reported=0 THEN 3
WHEN confirmed = 0 and cancelled=0 and discarded=0 and reported=4 THEN 4
ELSE 5 END,@id FROM '+@server+'.'+@db+'.dbo.fire where raised_dt>@time and tower_id=@id order by raised_dt desc';
Exec sp_executesql @InsertFireSql,N'@id nvarchar(50),@time DateTime',@id=@deviceID,@time=@fireReportTime;
print CONVERT(varchar(100), GETDATE(),21)+'.插入火情信息数据,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条'
--15.插入设备状态数据
--首先判断在视图中是否存在设备运行状态
declare @SearchViewSql Nvarchar(max)=N'SELECT tower_id FROM '+@server+'.'+@db+'.dbo.vw_cruise_state where tower_id=@id ';
Exec sp_executesql @SearchViewSql,N'@id nvarchar(50)',@id=@deviceID;
if @@ROWCOUNT>0
begin
declare @InsertDeviceStatusSql Nvarchar(max)=N'Insert into dbo.DeviceStatus(UnityID,GetTime,Status) SELECT tower_id,GETDATE(),aa_status FROM '+@server+'.'+@db+'.dbo.vw_cruise_state where tower_id=@id ';
Exec sp_executesql @InsertDeviceStatusSql,N'@id nvarchar(50)',@id=@deviceID;
print CONVERT(varchar(100), GETDATE(),21)+'插入设备运行状态数据,一共执行'+convert(varchar(5),@@ROWCOUNT)+'条';
print CONVERT(varchar(100), GETDATE(),21)+'设备ID为:'+@deviceID;
end
IF @@error=0
UPDATE #Tmp SET FlagID=1 WHERE deviceId = @deviceID
Return_device:
end
truncate table #Tmp;
exec sp_dropserver @server, 'droplogins ';
IF @@error=0
UPDATE @tRemoteOffice SET FlagID=1 WHERE RemoteSsid = @ssid
Return_Lab:
end
DROP TABLE [dbo].#Tmp
END TRY-----------结束捕捉异常
BEGIN CATCH------------有异常被捕获
print @@error;
--IF @@TRANCOUNT > 0---------------判断有没有事务
--BEGIN
-- ROLLBACK TRAN----------回滚事务
--END
print ERROR_MESSAGE();
UPDATE @tRemoteOffice SET FlagID=1 WHERE RemoteSsid = @ssid;
exec sp_dropserver @server, 'droplogins '; -----------执行存储过程将错误信息记录在表当中
END CATCH--------结束异常处理
end
存储过程使用表变量或临时表代替游标Fetch实例,访问远程数据库的更多相关文章
- MYSQL 存储过程、函数、临时表、游标
创建函数 因为我们平时经常需要创建不同日期的数据,以模拟的场景,覆盖更多的用例,所以这里写了一个返回随机日期的demo.大家可以自行扩展. DROP FUNCTION IF EXISTS milan_ ...
- sqlserver 表循环-游标、表变量、临时表
SQL Server遍历表的几种方法 阅读目录 使用游标 使用表变量 使用临时表 在数据库开发过程中,我们经常会碰到要遍历数据表的情形,一提到遍历表,我们第一印象可能就想到使用游标,使用游标虽然直观易 ...
- SQL表变量与临时表区别 + 非游标临时表遍历
SQL表变量与临时表区别 + 非游标临时表遍历 分类: SQL Server2009-11-27 17:01 1196人阅读 评论(2) 收藏 举报 sqlinsert存储sql servermicr ...
- sql server 存储过程中使用变量表,临时表的分析(续)
最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及. 在存储过程中使用临时表或变量表,使 ...
- SQL知识整理一:触发器、存储过程、表变量、临时表
触发器 触发器的基础知识 create trigger tr_name on table/view {for | after | instead of } [update][,][insert][,] ...
- SQL Server存储过程和游标有关实例以及相关网址
内含游标的存储过程实例 第一种写法 GO BEGIN IF (object_id('PT_FAULT_REPORT', 'P') is not null) drop proc PT_FAULT_REP ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- SQL Server 表变量和临时表的区别
SQL Server 表变量和临时表的区别 一.表变量 表变量在SQL Server 2000中首次被引入.表变量的具体定义包括列定义,列名,数据类型和约束.而在表变量中可以使用的约束包括主键约束,唯 ...
- SqlServer之表变量和临时表
表变量: 表变量创建的语法类似于临时表,区别就在于创建的时候,必须要为之命名.表变量是变量的一种, 表变量也分为本地及全局的两种,本地表变量的名称都是以"@"为前缀,只有在本地当前 ...
随机推荐
- MHA环境搭建【4】manager相关依赖的解决
mha的manager 结点依赖与mha-node软件包.所以在安装mha-manager之前要把mha-node安装上去:再者mha-manger还依赖于perl-Config-Tiny perl- ...
- package.json 的语法解释
https://www.ijser.cn/npm-package-json-document/ 形式可以有如下多种: version 严格匹配某个版本 >version 必须大于某个版本 > ...
- [LA] 3027 - Corporative Network [并查集]
A very big corporation is developing its corporative network. In the beginning each of the N enterpr ...
- 转载收藏之用 - 微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK
Senparc.Weixin.MP SDK已经涵盖了微信5.0的所有公共API,以及2013年10月29日升级之后大部分实用的接口. 整个项目的源代码以及已经编译好的程序集可以在这个项目中获取到:ht ...
- redhat 5下源码安装nginx服务
首先确保机器中已安装 gcc c++,libtool等工具,保证可执行源码安装 A.为了确保能在 Nginx 中使用正则表达式进行更灵活的配置,安装之前需要确定系统是否安装有 PCRE(Perl Co ...
- BZOJ 1264 基因匹配Match(LCS转化LIS)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1264 题意:给出两个数列,每个数列的长度为5n,其中1-n每个数字各出现5次.求两个数列 ...
- 暴力破解UltraEdit v21 无需注册
一.复制一份UltraEdit安装目录中的主程序uedit32.exe,到任意目录,用UltraEdit打开复制的uedit32.exe文件. 二.修改以下内容 原来:00094750h: BE DC ...
- 【HDU1325】Is It A Tree?(并查集基础题)
有以下坑点: 1.结束输入不一定-1,题目中的叙述只是说所有权值都为正值. 2.是否构成一棵树不能只判断是否只有一个根节点,没有环路,而且还需要判断每个节点的入度一定是1,不然就不是一棵树. (无环路 ...
- 【转】第一个MiniGUI程序:模仿QQ界面
最近几天在学MiniGui,最好的学习方法就是实践,先写个练练笔.其实只是一个界面,不知道什么时候才能真正写个完整的程序.初次写GUI程序,感觉写得不好,还请高手来指教. //============ ...
- QT 4.7支持中文(QT4.7)(中文)(makeqpf)
QT 4.7支持中文(QT4.7)(中文)(makeqpf) 摘要: QT4.7.0在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器 ...