首先这个流程要实现的功能大致是:

有两台服务器,一台是对外网开发的,一台是内网的。那么很明显数据交互都是外网服务器在做,而这个流程要做的就是要将外网上面的数据定时同步到内网中。

我们依对其中某张表的操作为例子,通过在一张基表(Staff)上面建立触发器,用来监督Staff表的增,删,改

由触发器将修改的内容的主键ID,表名称,以及所执行的动作(增,删,改),和修改内容的时间。记录到一张日志表中(ActionLog)

然后再由作业调用SSIS及BCP将修改的内容记录到一个txt文件中,随后对txt文件进行打包。

这样当其他的程序或者作业再去调用这个打包后的文件,并把它进行处理,就可以实现数据的同步工作了。

首先要新建一个SSIS项目,通过"文件 - 新建 - 项目 - Integration Services 项目",输入名称和项目位置之后,创建SSIS项目

创建完成之后,默认会进入到控制流的选项卡界面,这时候先不要着急走流程,首先创建几个用于流程的变量,在菜单栏上的"SSIS - 变量"点击创建

(以下变量或变量赋予的默认值,根据自己项目中的实际情况决定,仅供参考)

Flag(存放压缩包文件路径,String),

OutputPath(压缩包文件路径,String),

prefix(压缩包文件前缀,String,值:ylstf_),

TableName(需要操作的表名称,String,值:Staff),

TopNum(每次需要操作多少条数据,Int32,值:20),

TxtDataPath(存放TXT文件的路径,String,值:D:\Data_sync\YlStf\Temp\)

接下来我们所有的操作都会在SSIS设计中的控制流选项卡下进行操作

首先从左边“工具栏”的“控制流项”中,拖拽脚本任务到右边的控制流选项卡下,并将该脚本任务的名字改成“调用存储过程BCP出数据”,双击脚本进入脚本任务编辑器

在“脚本”选项的ReadOnlyVariables中选择prefix,TableName,TopNum,TxtDataPath 变量,ReadWriteVariables中选择Flag,OutputPath变量。

然后点击“编辑脚本”进入代码编辑

public void Main()
{
DateTime dtime = DateTime.Now;
SqlConnection con = new SqlConnection("你的数据库链接地址");
SqlCommand cmd = new SqlCommand("[Data_SYNC_Stf]", con); string dataPackPath = @"D:\Data_sync\Upload\";
string DataPath = Dts.Variables["TxtDataPath"].Value.ToString(); cmd.Parameters.Add("@table", SqlDbType.VarChar, ).Value = Dts.Variables["TableName"].Value;
cmd.Parameters.Add("@mInitialFilePath", SqlDbType.VarChar, ).Value = DataPath;
cmd.Parameters.Add("@mUploadFilePath", SqlDbType.VarChar, ).Value = dataPackPath;
cmd.Parameters.Add("@dateflag", SqlDbType.DateTime).Value = dtime;
cmd.Parameters.Add("@prefix", SqlDbType.VarChar, ).Value = Dts.Variables["prefix"].Value;
cmd.Parameters.Add("@TopNum", SqlDbType.Int).Value = ;
cmd.Parameters.Add("@DataFullFileName", SqlDbType.VarChar, ).Value = "";
cmd.Parameters["@DataFullFileName"].Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = ;
try
{
con.Open();
cmd.ExecuteNonQuery();
Dts.Variables["Flag"].Value = cmd.Parameters["@DataFullFileName"].Value.ToString(); System.IO.FileInfo fileinfo = new System.IO.FileInfo(DataPath + Dts.Variables["TableName"].Value + ".txt");
if (fileinfo.Length < )
{
throw new Exception("Empty files!!!!!!!!!!!!!!!!!!!!!!!");
} Dts.Variables["OutputPath"].Value = " a -ap -df " + Dts.Variables["Flag"].Value + " " + DataPath;
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
Dts.Events.FireError(, "Event Snippet", ex.Message, "", );
Dts.TaskResult = (int)ScriptResults.Failure;
}
finally { if (con.State == ConnectionState.Open) { con.Close(); } } }

代码中的Dts是 Microsoft.SqlServer.Dts.Runtime命名空间下的一个属性,Dts.Variables["变量名"].value 是获取SSIS中定义的变量值 Dts.Variables["变量名"].Value =“” 则是为变量赋值。
如果你不能找到Dts这个属性,那么请在引用中引入:Microsoft.SqlServer.ManagedDTS,Microsoft.SqlServer.ScriptTask 这两个dll文件

上面的代码中调用了一个存储过程[Data_SYNC_Stf],我们的BCP工作也就是在这里面完成的

Create PROCEDURE [dbo].[Data_SYNC_Stf]
@table VARCHAR() ,
@mInitialFilePath VARCHAR() , --数据包路径
@mUploadFilePath VARCHAR() , --上传的压缩文件路径
@DateFlag DATETIME , --打包日期
@TopNum INT, --每次多少条
@prefix varchar() ,--文件名前缀
@DataFullFileName VARCHAR() OUTPUT --要上传的数据包完整路径 AS
BEGIN DECLARE @__error_message NVARCHAR() --错误信息
DECLARE @err INT --错误数记录
BEGIN TRY
SET @DataFullFileName=@mUploadFilePath + @prefix + replace(replace(replace(convert(varchar,@DateFlag,),'-',''),' ',''),':','')+'.zip'
--SELECT * FROM actionlog WITH (HOLDLOCK);
--检查ActionLogTempStorage表是否还有没传完的。 没有则新插
DECLARE @count INT
SELECT @count = COUNT()
FROM dbo.ActionLogTempStorage
WHERE objTable = @table --AND state = IF @count =
BEGIN
INSERT INTO dbo.ActionLogTempStorage
( objID ,
objtable ,
objaction ,
createDate
)
SELECT TOP objid ,
objtable ,
objaction ,
@DateFlag
FROM dbo.actionlog
WHERE objtable = @table DELETE FROM dbo.actionlog
WHERE objID IN (
SELECT objID
FROM dbo.ActionLogTempStorage) END
--SELECT * FROM actionlog WITH (noLOCK); --开始导出各表操作=======================================
DECLARE @sql VARCHAR() --打包ActionTemp中需要插入的表记录 SET @sql = 'bcp "SELECT top '''+@TopNum +''' a.* FROM dbo.Staff AS a RIGHT JOIN dbo.ActionLogTempStorage AS b on a.ID=b.[objID] where b.objTable='''+@table+''' and b.state=0 and (b.objAction=1 or b.objAction=2)" queryout ' + @mInitialFilePath + @table+'.txt -c -T -r{_r} -t {_t}' PRINT @sql EXEC master.dbo.xp_cmdshell @sql END TRY
BEGIN CATCH
--错误处理
SET @err = @@error
SELECT @__error_message = ERROR_MESSAGE()
INSERT dbo._SYNCERROR
( MSG )
VALUES ( @table + @__error_message )
END CATCH
END

如果你的master.dbo.xp_cmdshell 存储过程执行的有误,那么请在调用这个存储过程的前面加上:
 --启用xp_cmdshell 所属的高级配置项
 EXEC sp_configure 'show advanced options', 1 ;
 RECONFIGURE ;

--启用xp_cmdshell
 EXEC sp_configure 'xp_cmdshell', 1 ;
 RECONFIGURE ;

接着在控制流中,拖拽执行进程任务的控制流项,双击进入任务编辑器。

在处理中的Executable选择WinRAR(或其他压缩包)程序,WorkingDirectory选择WinRAR(或其他压缩包)程序文件夹

如我的是,Executable:C:\Program Files\WinRAR\WinRAR.exe,WorkingDirectory:C:\Program Files\WinRAR\,设置完成之后点击确定

再从左边的工具栏里面拖拽“脚本任务”控制流项,名字改为“完成并产生OK标记”(打包完成之后会生成两个压缩包,一个是存放数据的压缩包,另一个是_ok.zip压缩包,有这个带ok的压缩包文件,说明是成功的打包文件,否则就认为是错误的文件)

同样双击编辑,进入脚本任务编辑器。在ReadOnlyVariables中选择:Flag,OutputPath,TableName变量,点击“编辑脚本”

 public void Main()
{
DateTime dtime = DateTime.Now;
SqlConnection con = new SqlConnection("你的数据库链接地址");
string TableName = Dts.Variables["TableName"].Value.ToString();
string Flag = Dts.Variables["Flag"].Value.ToString();
List<string> sqlList = new List<string>(); string sql = "INSERT INTO dbo.ActionTemp (objID,objtable,objAction,createDate,[state],DataFileName) SELECT ";
sql += "objid ,objtable , objaction , GETDATE() , 1, ";
sql += "'" + Dts.Variables["Flag"].Value + "'";
sql += " FROM dbo.ActionLogTempStorage WHERE objTable = '" + TableName + "'";
sqlList.Add(sql); sqlList.Add("DELETE FROM dbo.ActionLogTempStorage WHERE objTable ='" + TableName + "';");
try
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
for (int i = ; i < sqlList.Count; i++)
{
cmd.CommandText = sqlList[i].ToString();
if (cmd.ExecuteNonQuery() >= )
{
continue;
}
else
{
throw new Exception(" back db error sql str:" + sql[i]);
}
}
string Dataflag = Flag.Replace(".zip", "_ok.zip");
System.IO.File.Create(Dataflag).Dispose();
Dts.TaskResult = (int)ScriptResults.Success; }
catch (Exception ex)
{
if (File.Exists(Flag))
{
File.Delete(Flag);
}
if (File.Exists(Flag.Replace(".zip", "_ok.zip")))
{
File.Delete(Flag.Replace(".zip", "_ok.zip"));
}
Dts.Events.FireError(, "Err", "LastStep Error:" + ex.Message, "", );
Dts.TaskResult = (int)ScriptResults.Failure;
}
finally { if (con.State == ConnectionState.Open) { con.Close(); } }
}

到这里SSIS的开发流程已经完成了。我们可以通过刚刚创建项目的路径找到.dtsx文件放到需要调用的服务器上面

下面开始通过作业调用SSIS:

在作业“属性”的“步骤”中“新建”一个步骤,

类型选择“Sql Server Integration Services包”,

用行身份选择“Sql Server代理服务帐号”,

包源选择“Sql Server”,

使用Windows身份验证或使用Sql Server 身份验证(输入用户名和密码)都可以,

包选择你把.dtsx放的地方

作业的其他地方根据服务器的要求自己设定即可。

作业创建好之后,运行一下作业,看看有没有在指定的路径下面生成压缩包文件和_ok压缩包文件。

以及ActionLog和ActionTemp中的数据是否有变化,就可以判断SSIS包有没有执行成功了!

SSIS结合BCP及SQL Server作业实现定时将数据导出打包实现数据同步的更多相关文章

  1. SQL Server 作业监控

    原文:SQL Server 作业监控 在讲解SQLServer Agent Jobs之前,先要讲解msdb. Msdb是SQLServer的系统数据库之一,用于存储SQLServer的配置.元数据等信 ...

  2. SQL SERVER作业的Schedules浅析

    SQL SERVER作业的计划(Schedules),如果你没仔细研究过或没有应用一些复杂的计划(Schedules),那么你觉得SQL SERVER作业的计划(Schedules)非常好用,也没啥问 ...

  3. 【解决】SQL Server作业中Excel Application不能访问文件

    在通过SQL Server作业来实现定时任务时,出现如下错误: FullyQualifiedErrorId : ComMethodTargetInvocation使用“1”个参数调用“Add”时发生异 ...

  4. SQL SERVER 作业(或叫执行计划)

    如果在SQL Server 里需要定时或者每隔一段时间执行某个存储过程或3200字符以内的SQL语句时,可以用管理->SQL Server代理->作业来实现. 1.管理->SQL S ...

  5. SQL Server作业没有执行的解决方法

    SQL Server作业没有执行的解决方法  确保SQL Agent服务启动,并设置为自动启动,否则你的作业不会被执行    设置方法:  我的电脑--控制面板--管理工具--服务--右键 SQLSE ...

  6. SQL SERVER 作业问题(SET 选项的设置不正确: 'QUOTED_IDENTIFIER'。),以及其它定时sql执行方式探索

    在实时曲线测试平台中,需要用到实时测试数据作为依据,评估程序的可靠性.在编写sql server作业时,出现了一些问题,经过研究给予解决,供大家参考. 1.编写脚本如下: declare @i int ...

  7. SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)

    1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地 ...

  8. sql server 使用链接服务器连接Oracle,openquery查询数据

      对接问题描述:不知道正式库oracle数据库账户密码,对方愿意在对方的客户端上输入账号和密码,但不告诉我们 解决方案:使用一台sql server作为中间服务器,可以通过转存数据到sql serv ...

  9. SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条

    SQL Server分页语句ROW_NUMBER,读取第4页数据,每页10条 SELECT Id,[Title],[Content],[Image] FROM ( SELECT ROW_NUMBER( ...

随机推荐

  1. 如何使用eclipse进行嵌入式Linux的开发

    如何使用eclipse进行嵌入式Linux的开发 作者:曾宏安,华清远见嵌入式学院高级讲师. 如何使用eclipse进行嵌入式Linux的开发 习惯了在windows环境下开发的程序员在转到Linux ...

  2. Spring面试题汇总

    一.Spring最核心的功能是什么?使用Spring框架的最核心的原因是什么? Spring 框架中核心组件有三个:Core.Context 和 Beans.其中最核心的组件就是Beans, Spri ...

  3. CONTAINING_RECORD 宏

    Windows中提供了一个宏 #define CONTAINING_RECORD (address, type, field ) ((type *)( \ (PCHAR)(address ) - \ ...

  4. NOIP2015 提高组(senior) 解题报告

    过了这么久才来发解题报告,蒟蒻实在惭愧 /w\ Day1 T1 [思路] 模拟 [代码] #include<iostream> #include<cstring> #inclu ...

  5. 初来咋到先试试windows live writer

    据说这个工具用来写博客很好用的,先试试哦... 来说说具体使用方法吧:(摘抄自博客园) 下面首先讲用Windows Live Writer 2012发博客: 一.软件准备: 最新版的是Windows ...

  6. [读书笔记]算法(Sedgewick著)·第二章.初级排序算法

    本章开始学习排序算法 1.初级排序算法 先从选择排序和插入排序这两个简单的算法开始学习排序算法.选择排序就是依次找到当前数组中最小的元素,将其和第一个元素交换位置,直到整个数组有序. public s ...

  7. 使用Jquery.load()方法,出现-此页的状态信息无效,可能已损坏。[转]

    今天遇到此页的状态信息无效,可能已损坏,在以下页面找到解决办法,特记录下来: 转自:http://www.cnblogs.com/liuwenlong/archive/2011/05/09/20410 ...

  8. 问题-delphi 调试(F8)错行处理

    在delphi 7中(其他版本也可能碰到该问题),编译后,代码左边显示蓝色小点,表示哪句代 码是被编译了的,可今天我的一些代码不能显示那些蓝点了,这样也就不能在上面设断点了,而且用F8跟踪发现执行的顺 ...

  9. Xcode5 上使用Base SDK iOS6程序和iOS6模拟器

    Xcode 5默认自带SDK 7.0,升级Xcode 5后,Xcode.5就没了,这样我想编译SDK 6.x的程序就难办了(除非同时安装Xcode 4.x和Xcode 5.x两个版本Xcode).其中 ...

  10. 掌握jQuery插件开发

    进行jQuery插件开发前,首先要知道两个问题:什么是jQuery插件?jQuery插件如何使用? 第一个问题,jQuery插件就是用来扩展jQuery原型对象的一个方法,简单来说就是jQuery插件 ...