将Oracle表与SQL Server表比较

问题描述:

我正在寻找一种比较Oracle和SQL Server表之间数据的有效方法。我无法控制Oracle表,只能执行select查询。该表包含30,000多行。目前,我从Oracle表创建一个数据集,然后将数据与我所维护的SQL Server表进行比较。在这种情况下,我只是检查SQL Server表中是否存在学号。在数字不存在的情况下,我将它插入到SQL Server表中。正如你所能想象的那样,这是非常低效的。你的建议和例子将不胜感激。将Oracle表与SQL Server表比较

+1

1. SQL是一种查询语言。你的意思是SQL Server? 2. *你想要做什么?你已经描述了*你是如何做到的。 – Ronnis 2010-12-17 21:49:28

+0

SQL Server。最终目标是执行早上报告并仅捕获oracle表中的新学生,然后将它们复制到我的sql服务器表中。 – gnome 2010-12-17 22:00:18

使用可在Oracle实例上访问的帐户在SQL Server上创建一个Linked Server instance

然后,您可以使用缺少的内容更新SQL Server表:

INSERT INTO [SQLServer].[dbo].[table] 
SELECT columns 
    FROM [Oracle].[database].[schema].[table] x 
WHERE NOT EXISTS(SELECT NULL 
        FROM [SQLServer].[dbo].[table] y 
        WHERE y.student_number = x.student_number) 

有没有在和LEFT JOIN/IS NULL的替代品 - NOT IN and NOT EXISTS perform better than LEFT JOIN/IS NULL when the columns compared (in this case, student_number) is not nullable (the value can never be NULL)

很容易script this as a SQL Server Agent Job if you need it to run periodically

+0

+1。我尝试了这样一种方式,但是在涉及CLOB列的时候它不起作用。我不知道这是由于某些代码页不兼容造成的还是OLEDB的一般限制(链接服务器似乎使用OLEDB)。没有那些有问题的专栏,它的工作真的很好。 – 2010-12-18 16:01:18

+0

这看起来好像会起作用,但它是否需要在服务器上进行其他设置/配置。我无法控制这些。 – gnome 2010-12-20 15:09:24

我不确定这是否是一个好的答案,因为我很难看到您要求的内容,但我个人会将处理负担转移到RDBMS上。所以相反,你会创建一个单一的选择语句算法,只会返回相关的值。

这可以通过使用NOT IN sql操作符来完成。然而

所以开始你的字符串,你通常会...

String statement = "SELECT * FROM OracleDB where StudentID NOT IN ("; 
foreach (val in StudentIDValuesFromYourDB) 
{ 
    statement = statement.concat(val + ", "); 
} 
statement = statement.substring(0,statement.length()-2);//remove the extra comma 
statement = statement.concat(")"); 

诚然这是一个巨大的声明,我不知道,如果它甚至允许那么大(我也不是肯定的Oracle语法,我讨厌为Oracle客户端调整我的工作),但我认为RDBMS会更好地为您完成所有这些排序工作而优化。如果你可以运行这个语句,你只会得到OracleDB中的值,而不是在你自己的DB中。

您现在可以使用此列表仅生成相关的插入语句。

+0

不要太陈述太大。但感谢您的建议。 – gnome 2010-12-20 15:23:23

+0

哈哈,我很害怕那个。 – gnomed 2010-12-20 18:37:52

一个简单的SSIS包就足够了。编写一个数据流任务,从Oracle和SQLServer获取数据,这是一个查找控件,可以在它们之间进行比较,并在失败时进行更新,并在成功时插入。 SSIS的设计非常快速和高效。

+0

正是我正在打字,但你击败了我的输入键。通过一个软件包,您可以安排它在报告运行之前的每一天运行。 – HLGEM 2010-12-17 22:25:44

+0

@HLGEM下次好运:-)。你在那里做的好点。 – 2010-12-17 22:37:49

谢谢大家的意见。 OMG Ponies,你会得到这张支票,因为它是我需要的正确解决方案。但是,服务器没有链接。所以我不得不写一个使用linq的解决方法。

首先,我改变了Oracle数据集到一个对象:

List<Student> studentList = new List<Student>(); 
studentList = (from d in dataSet 
    select new Student 
    { 
     StudentNumber = d.STUDENTNUMBER, 
     .... other properties 
    }).ToList(); 

然后我写了一个comparer class和返回的区别:

public IEnumerable<Student> ListNewStudents(IEnumerable<Student> studentList) 
{ 

    List<Student> otherStudentList = (from s in _dataContext.Students 
     select new Student 
     { 
      StudentNumber = s.StudentNumber 
     }).ToList(); 

    return studentList.Except(otherStudentList, new StudentComparer()).ToList(); 
} 

完美的工作,我又是一个快乐的人。