SQL Server 与 Oracle 建立DbLink
用以下方法行不通:
1.用Oracle的NetManager创建服务命名,如“ORCL”
2.在SQL查询分析器中执行以下脚本建立链接服务器
EXEC sp_addlinkedserver
@server = 'ORCL',
@srvproduct = 'Oracle',
@provider = 'MSDAORA',
@datasrc = 'ORCL'
3.在SQL查询分析器中执行以下脚本设置链接服务器登录帐号:“scott/tiger”
EXEC sp_addlinkedsrvlogin 'ORCL', 'FALSE',NULL, 'scott', 'tiger'
4.在SQL查询分析器中执行以下脚本测试链接服务器设置是否OK
SELECT * FROM ORCL..SCOTT.EMP
后把连接驱动改成Oracle Provider for OLE DB之后,就可以在企业管理器中看到Oracle数据库中的表了,SELECT * FROM ORCL..SCOTT.EMP时一定要大写。但还是出现如下错误:错误7320,级别 16,状态 2,行 1 未能对 OLE DB 提供程序 'Microsoft.Jet.OLEDB.4.0' 执行查询。解决办法:在驱动选项上把“允许InProcess”勾起,就OK了。
参考资料:http://dingfeng-cn.spaces.live.com/blog/cns!24ad96ecbc21cefa!124.entry
将SQL Server数据同步到Oracle:
Code
/**********************************************
A:SQL数据库A,调度库,建有SynchTotbCLog(日志表)、Job
B:SQL数据库B,数据源库,建有tbB表
C:Oracl数据库,建有目标表tbC
说明:同期性批量取源记录,逐行插入到目标表,若某个周期有失败,可从job日志中看到。
************************************************/
--假定 Oracle 数据库的 SQL*Net 别名为 MyServer。
GO
EXEC sp_addlinkedserver
@server = 'C',
@srvproduct = 'Oracle',
@provider = 'MSDAORA',
@datasrc = 'MyServer'
GO
--建立链接服务器srvB
/****** 对象: LinkedServer [srvB] 脚本日期: 12/23/2008 10:07:56 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'srvB', @srvproduct=N'SQL Server'
/* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'srvB',@useself=N'False',@locallogin=NULL,@rmtuser=N'srvBAccount',@rmtpassword='########'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'srvB',@useself=N'False',@locallogin=N'ieduser',@rmtuser=N'srvBAccount',@rmtpassword='########'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'rpc', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'use remote collation', @optvalue=N'true'
-- 建立存储过程
GO
USE A
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
-- =============================================
-- Author:
-- Create date: 2008-12-23
-- Description: 同步B库tbB表中更新时间大于同步时间的记录到C库tbC表中
-- ID为tbB、tbC表的关键字,R_MODIFY_DATE为更新时间
-- =============================================
CREATE PROCEDURE [dbo].[spAutoSynchTotbC]
AS
BEGIN
DECLARE @dtSynch DATETIME
DECLARE @tbTime DATETIME
-- 最后一次同步时间,如果没有,则为1900-01-01
SELECT TOP 1 @dtSynch=SynchTime FROM dbo.SynchTotbCLog WHERE STableName='tbB' AND DTableName='tbC' ORDER BY SynchTime DESC
IF @dtSynch IS NULL SET @dtSynch='1900-01-01'
SET @tbTime=GETDATE()
-- 选出更新时间大于最后一次同步时间的记录集
DECLARE cstbBs CURSOR
READ_ONLY
FOR SELECT ID AS FileRecKey,R_MODIFY_DATE FROM dbo.[tbB] WHERE R_MODIFY_DATE>=@dtSynch ORDER BY R_MODIFY_DATE ASC
DECLARE @RecKey VARCHAR(30)
DECLARE @R_MODIFY_DATE DATETIME
OPEN cstbBs
-- 循环同步
FETCH NEXT FROM cstbBs INTO @RecKey,@R_MODIFY_DATE
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
-- 如果目标表中存在此ID的记录,那么更新目标表,否则插入新的
IF EXISTS(SELECT ID FROM dbo.tbC WHERE ID=@RecKey)
BEGIN
UPDATE C.dbo.tbC SET fldCA=S.fldBA,
FROM srvB.B.dbo.[tbB] S
WHERE C.tbC.ID=S.ID AND S.ID=@RecKey
SET @tbTime=@R_MODIFY_DATE
--写同步日志
IF EXISTS(SELECT * FROM [SynchTotbCLog] WHERE [STableName]='tbB' AND [DTableName]='tbC')
BEGIN
UPDATE [SynchTotbCLog] SET [SynchTime]=@tbTime WHERE [STableName]='tbB' AND [DTableName]='tbC'
END
ELSE
BEGIN
INSERT INTO [SynchTotbCLog]([STableName],[DTableName],[SynchTime])
VALUES ('tbB','tbC',@tbTime)
END
END
ELSE
BEGIN
INSERT C.dbo.tbC(A,B,)
SELECT A,B,
FROM srvB.B.dbo.[tbB]
WHERE ID=@RecKey
SET @tbTime=@R_MODIFY_DATE
--写同步日志
IF EXISTS(SELECT * FROM [SynchTotbCLog] WHERE [STableName]='tbB' AND [DTableName]='tbC')
BEGIN
UPDATE [SynchTotbCLog] SET [SynchTime]=@tbTime WHERE [STableName]='tbB' AND [DTableName]='tbC'
END
ELSE
BEGIN
INSERT INTO [SynchTotbCLog]([STableName],[DTableName],[SynchTime])
VALUES ('tbB','tbC',@tbTime)
END
END
END
FETCH NEXT FROM cstbBs INTO @RecKey,@R_MODIFY_DATE
END
CLOSE cstbBs
DEALLOCATE cstbBs
END
GO
---建立Job
USE [msdb]
GO
/****** 对象: Job [同步到Oracl库] 脚本日期: 12/23/2008 09:21:56 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** 对象: JobCategory [[Uncategorized (Local)]]] 脚本日期: 12/23/2008 09:21:56 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'同步到Oracl库',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'无描述。',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'SQL帐号XXX', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** 对象: Step [step1] 脚本日期: 12/23/2008 09:21:57 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'step1',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXEC spAutoSynchTotbC',
@database_name=N'A',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'sch1',
@enabled=1,
@freq_type=8,
@freq_interval=62,
@freq_subday_type=4,
@freq_subday_interval=2,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20081223,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave:
/**********************************************
A:SQL数据库A,调度库,建有SynchTotbCLog(日志表)、Job
B:SQL数据库B,数据源库,建有tbB表
C:Oracl数据库,建有目标表tbC
说明:同期性批量取源记录,逐行插入到目标表,若某个周期有失败,可从job日志中看到。
************************************************/
--假定 Oracle 数据库的 SQL*Net 别名为 MyServer。
GO
EXEC sp_addlinkedserver
@server = 'C',
@srvproduct = 'Oracle',
@provider = 'MSDAORA',
@datasrc = 'MyServer'
GO
--建立链接服务器srvB
/****** 对象: LinkedServer [srvB] 脚本日期: 12/23/2008 10:07:56 ******/
EXEC master.dbo.sp_addlinkedserver @server = N'srvB', @srvproduct=N'SQL Server'
/* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'srvB',@useself=N'False',@locallogin=NULL,@rmtuser=N'srvBAccount',@rmtpassword='########'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'srvB',@useself=N'False',@locallogin=N'ieduser',@rmtuser=N'srvBAccount',@rmtpassword='########'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'collation compatible', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'data access', @optvalue=N'true'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'dist', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'pub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'rpc', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'rpc out', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'sub', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'connect timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'collation name', @optvalue=null
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'lazy schema validation', @optvalue=N'false'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'query timeout', @optvalue=N'0'
GO
EXEC master.dbo.sp_serveroption @server=N'srvB', @optname=N'use remote collation', @optvalue=N'true'
-- 建立存储过程
GO
USE A
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
-- =============================================
-- Author:
-- Create date: 2008-12-23
-- Description: 同步B库tbB表中更新时间大于同步时间的记录到C库tbC表中
-- ID为tbB、tbC表的关键字,R_MODIFY_DATE为更新时间
-- =============================================
CREATE PROCEDURE [dbo].[spAutoSynchTotbC]
AS
BEGIN
DECLARE @dtSynch DATETIME
DECLARE @tbTime DATETIME
-- 最后一次同步时间,如果没有,则为1900-01-01
SELECT TOP 1 @dtSynch=SynchTime FROM dbo.SynchTotbCLog WHERE STableName='tbB' AND DTableName='tbC' ORDER BY SynchTime DESC
IF @dtSynch IS NULL SET @dtSynch='1900-01-01'
SET @tbTime=GETDATE()
-- 选出更新时间大于最后一次同步时间的记录集
DECLARE cstbBs CURSOR
READ_ONLY
FOR SELECT ID AS FileRecKey,R_MODIFY_DATE FROM dbo.[tbB] WHERE R_MODIFY_DATE>=@dtSynch ORDER BY R_MODIFY_DATE ASC
DECLARE @RecKey VARCHAR(30)
DECLARE @R_MODIFY_DATE DATETIME
OPEN cstbBs
-- 循环同步
FETCH NEXT FROM cstbBs INTO @RecKey,@R_MODIFY_DATE
WHILE (@@fetch_status <> -1)
BEGIN
IF (@@fetch_status <> -2)
BEGIN
-- 如果目标表中存在此ID的记录,那么更新目标表,否则插入新的
IF EXISTS(SELECT ID FROM dbo.tbC WHERE ID=@RecKey)
BEGIN
UPDATE C.dbo.tbC SET fldCA=S.fldBA,
FROM srvB.B.dbo.[tbB] S
WHERE C.tbC.ID=S.ID AND S.ID=@RecKey
SET @tbTime=@R_MODIFY_DATE
--写同步日志
IF EXISTS(SELECT * FROM [SynchTotbCLog] WHERE [STableName]='tbB' AND [DTableName]='tbC')
BEGIN
UPDATE [SynchTotbCLog] SET [SynchTime]=@tbTime WHERE [STableName]='tbB' AND [DTableName]='tbC'
END
ELSE
BEGIN
INSERT INTO [SynchTotbCLog]([STableName],[DTableName],[SynchTime])
VALUES ('tbB','tbC',@tbTime)
END
END
ELSE
BEGIN
INSERT C.dbo.tbC(A,B,)
SELECT A,B,
FROM srvB.B.dbo.[tbB]
WHERE ID=@RecKey
SET @tbTime=@R_MODIFY_DATE
--写同步日志
IF EXISTS(SELECT * FROM [SynchTotbCLog] WHERE [STableName]='tbB' AND [DTableName]='tbC')
BEGIN
UPDATE [SynchTotbCLog] SET [SynchTime]=@tbTime WHERE [STableName]='tbB' AND [DTableName]='tbC'
END
ELSE
BEGIN
INSERT INTO [SynchTotbCLog]([STableName],[DTableName],[SynchTime])
VALUES ('tbB','tbC',@tbTime)
END
END
END
FETCH NEXT FROM cstbBs INTO @RecKey,@R_MODIFY_DATE
END
CLOSE cstbBs
DEALLOCATE cstbBs
END
GO
---建立Job
USE [msdb]
GO
/****** 对象: Job [同步到Oracl库] 脚本日期: 12/23/2008 09:21:56 ******/
BEGIN TRANSACTION
DECLARE @ReturnCode INT
SELECT @ReturnCode = 0
/****** 对象: JobCategory [[Uncategorized (Local)]]] 脚本日期: 12/23/2008 09:21:56 ******/
IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name=N'[Uncategorized (Local)]' AND category_class=1)
BEGIN
EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'[Uncategorized (Local)]'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
END
DECLARE @jobId BINARY(16)
EXEC @ReturnCode = msdb.dbo.sp_add_job @job_name=N'同步到Oracl库',
@enabled=1,
@notify_level_eventlog=0,
@notify_level_email=0,
@notify_level_netsend=0,
@notify_level_page=0,
@delete_level=0,
@description=N'无描述。',
@category_name=N'[Uncategorized (Local)]',
@owner_login_name=N'SQL帐号XXX', @job_id = @jobId OUTPUT
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
/****** 对象: Step [step1] 脚本日期: 12/23/2008 09:21:57 ******/
EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=N'step1',
@step_id=1,
@cmdexec_success_code=0,
@on_success_action=1,
@on_success_step_id=0,
@on_fail_action=2,
@on_fail_step_id=0,
@retry_attempts=0,
@retry_interval=0,
@os_run_priority=0, @subsystem=N'TSQL',
@command=N'EXEC spAutoSynchTotbC',
@database_name=N'A',
@flags=0
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id=@jobId, @name=N'sch1',
@enabled=1,
@freq_type=8,
@freq_interval=62,
@freq_subday_type=4,
@freq_subday_interval=2,
@freq_relative_interval=0,
@freq_recurrence_factor=1,
@active_start_date=20081223,
@active_end_date=99991231,
@active_start_time=0,
@active_end_time=235959
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
COMMIT TRANSACTION
GOTO EndSave
QuitWithRollback:
IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
EndSave: