Java 使用JDBC将表从SQL Server复制到Oracle
我正在尝试将三个单独的表从SQL Server 2012加载到Oracle中。我已在单独的类中建立了与SQL Server和Oracle的连接,如下所示: SQL Server连接: Oracle连接: 我已将所有登录详细信息存储在属性文件中 我的第一个问题是如何结合这两个类来合并这两个连接?我的第二个问题是如何使用select语句从SQL Server获取所有数据,然后使用insert语句插入Oracle数据库 SQL Server和Oracle中的表(从SQL Server到Oracle) 1。对于材料批次:Java 使用JDBC将表从SQL Server复制到Oracle,java,mysql,sql-server,jdbc,oracle-sqldeveloper,Java,Mysql,Sql Server,Jdbc,Oracle Sqldeveloper,我正在尝试将三个单独的表从SQL Server 2012加载到Oracle中。我已在单独的类中建立了与SQL Server和Oracle的连接,如下所示: SQL Server连接: Oracle连接: 我已将所有登录详细信息存储在属性文件中 我的第一个问题是如何结合这两个类来合并这两个连接?我的第二个问题是如何使用select语句从SQL Server获取所有数据,然后使用insert语句插入Oracle数据库 SQL Server和Oracle中的表(从SQL Server到Oracle)
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL Server中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL开发人员中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
2。对于主控材料:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL Server中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL开发人员中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
3。对于供应商:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL Server中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
在SQL开发人员中:
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|EXPIRATION DATE|
MODIFIED_DATETIME
MATERIAL NUMBER|BATCH NUMBER|VENDOR BATCH NUMBER|VENDOR NUMBER|GOODS_SUPPLIER_NUMBER|
EXPIRATION DATE|INSTIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|MODIFIED_DATETIME
PLANT|MATERIAL_NUMBER|MATERIAL_DESC|PROFIT_CENTER_NAME|STATUS|INSTIME
VENDOR_NUMBER|VENDOR_NAME|MODIFIED_DATETIME
VENDOR_NUMBER|VENDOR_NAME|VENDOR_LOCATION|INSTIME
有些字段不在SQL Server中,而在SQL Developer(Oracle)中。对于那些我将保持
NULL
的人,这里有一些关于如何继续的草拟代码-它不会编译,因为缺少一些方法-但是您应该能够从这里填补空白
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBCopy {
public static void main(String[] args) {
try {
//You know how to do this - just rename and copy in...
Connection sourceCon = getOracleConnection();
Connection targetCon = geSqlServerConnection();
copyMaterialBatch(sourceCon, targetCon);
copyMaterialMaster(sourceCon, targetCon);
copyVendor(sourceCon, targetCon);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void copyMaterialBatch(Connection sourceCon, Connection targetCon) throws SQLException {
//Try-with-Resource to close all cursors once we're done
try(//SELECT from source
PreparedStatement ps = sourceCon.prepareStatement(
"SELECT \"MATERIAL NUMBER\", "
+ "\"BATCH NUMBER\", "
+ "\"VENDOR BATCH NUMBER\", "
+ "\"VENDOR NUMBER\", "
+ "\"EXPIRATION DATE\", "
+ "\"MODIFIED_DATETIME\" FROM MATERIAL_BATCH");
//INSERT into target
PreparedStatement ins = targetCon.prepareStatement(
"INSERT INTO MATERIAL_BATCH([MATERIAL NUMBER], "
+ "[BATCH NUMBER], "
+ "[VENDOR BATCH NUMBER], "
+ "[VENDOR NUMBER], "
+ "[GOODS_SUPPLIER_NUMBER], "
+ "[EXPIRATION DATE]"
+ "[INSTIME]) VALUES (?,?,?,?,NULL,?,?)");
//Perform select / open Cursor
ResultSet rs = ps.executeQuery()) {
int batchnr = 0;
int MAXBATCH = 100;
while(rs.next()) {
//Set into INSERT the values we SELECTEd
ins.setInt(1, rs.getInt("MATERIAL NUMBER"));
ins.setInt(2, rs.getInt("BATCH NUMBER"));
ins.setInt(3, rs.getInt("VENDOR BATCH NUMBER"));
ins.setInt(4, rs.getInt("VENDOR NUMBER"));
ins.setTimestamp(5, rs.getTimestamp("EXPIRATION DATE"));
ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
//Add to Batch (you could executeUpdate here but if you have los of rows...)
ins.addBatch();
if(++batchnr % MAXBATCH == 0) {
ins.executeBatch();
}
}
//if number of rows was not aligned on MAXBATCH size...
ins.executeBatch();
}
}
}
请注意,Oracle和SQL Server对包含空格的列名使用不同的转义。Oracle需要“COLUMN NAME”
,而SQL Server需要[COLUMN NAME]
祝你好运
编辑
适合您的实际参数类型:
//Set into INSERT the values we SELECTEd
ins.setString(1, rs.getString("MATERIAL_NUMBER"));
ins.setString(2, rs.getString("BATCH_NUMBER"));
ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER"));
ins.setString(4, rs.getString("VENDOR_NUMBER"));
ins.setString(5, rs.getString("GOODS_SUPPLIER_NUMBER"));
//6th value is always null as specified in INSERT
ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
因此,现在我得到了一个错误:列名称GOODS\u SUPPLIER\u NUMBER无效。因此,这是其中一列,它将被列为null,因为该列在源连接中不存在。以下是其取货地点的代码供应商编号。我知道我非常接近。关于这个有什么想法吗? 谢谢你,桑尼
private static void copyMaterialBatch(Connection sourceCon, Connection targetCon) throws SQLException {
//Try-with-Resource to close all cursors once we're done
try(//SELECT from source
PreparedStatement ps = sourceCon.prepareStatement(
"SELECT [MATERIAL_NUMBER], "
+ " [BATCH_NUMBER], "
+ " [VENDOR_BATCH_NUMBER], "
+ " [VENDOR_NUMBER], "
+ " [EXPIRATION_DATE], "
+ " [MODIFIED_DATETIME] FROM dbo.MATERIAL_BATCH_VIEW");
//INSERT into target
PreparedStatement ins = targetCon.prepareStatement(
"INSERT INTO MATERIAL_BATCH(MATERIAL_NUMBER, "
+ "BATCH_NUMBER, "
+ "VENDOR_BATCH_NUMBER, "
+ "VENDOR_NUMBER, "
**+ "GOODS_SUPPLIER_NUMBER, "**
+ "EXPIRATION_DATE"
+ "INSTIME) VALUES (?,?,?,?,NULL,?,?)");
//Perform select / open Cursor
ResultSet rs = ps.executeQuery()) {
int batchnr = 0;
int MAXBATCH = 1000;
while(rs.next()) {
//Set into INSERT the values we SELECTEd
ins.setString(1, rs.getString("MATERIAL_NUMBER"));
ins.setString(2, rs.getString("BATCH_NUMBER"));
ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER"));
ins.setString(4, rs.getString("VENDOR_NUMBER"));
ins.setString(5, rs.getString("GOODS_SUPPLIER_NUMBER"));
ins.setString(6, rs.getString("EXPIRATION_DATE"));
ins.setTimestamp(7, rs.getTimestamp("MODIFIED_DATETIME"));
//Add to Batch (you could executeUpdate here but if you have los of rows...)
ins.addBatch();
if(++batchnr % MAXBATCH == 0) {
ins.executeBatch();
}
}
因此,当我删除了货物\供应商\编号后,我的insert语句现在看起来是完整的:
try(//SELECT from source
PreparedStatement ps = sourceCon.prepareStatement(
"SELECT [PLANT], "
+ "[MATERIAL_NUMBER], "
+ "[MATERIAL_DESC], "
+ "[MODIFIED_DATETIME] FROM dbo.MATERIAL_MASTER_VIEW");
//INSERT into target
PreparedStatement ins = targetCon.prepareStatement(
"INSERT INTO MATERIAL_BATCH(MATERIAL_NUMBER, "
+ "BATCH_NUMBER, "
+ "VENDOR_BATCH_NUMBER, "
+ "VENDOR_NUMBER, "
+ "EXPIRATION_DATE"
+ "INSTIME) VALUES (?,?,?,?,?,?)");
//Perform select / open Cursor
ResultSet rs = ps.executeQuery()) {
int batchnr = 0;
int MAXBATCH = 1000;
while(rs.next()) {
//Set into INSERT the values we SELECTEd
ins.setString(1, rs.getString("MATERIAL_NUMBER"));
ins.setString(2, rs.getString("BATCH_NUMBER"));
ins.setString(3, rs.getString("VENDOR_BATCH_NUMBER"));
ins.setString(4, rs.getString("VENDOR_NUMBER"));
ins.setString(5, rs.getString("EXPIRATION_DATE"));
ins.setTimestamp(6, rs.getTimestamp("MODIFIED_DATETIME"));
现在insert语句中有6个值与ins.setString部分中的6个值匹配
我得到的错误是:java.sql.BatchUpdateException:ORA-00913:值太多
我认为最后一列中的INSTIME与MODIFIED_DATETIME不匹配
再一次,我会确保给你这个答案的信用。我只是不想重复代码,所以我把它放在回答我自己问题的地方。再次感谢
非常感谢你。成功了。还有一件事。因此,我有材料批次、材料主数据和供应商。由于某种原因,我得到了一个供应商的错误。错误是:列名“VENDOR\u name”无效
以下是供应商代码:
private static void copyVendor(Connection sourceCon, Connection targetCon) throws SQLException {
//Try-with-Resource to close all cursors once we're done
try(//SELECT from source
PreparedStatement ps = sourceCon.prepareStatement(
"SELECT [VENDOR_NUMBER], "
+ "[VENDOR_NAME], "
+ "[MODIFIED_DATETIME] FROM dbo.VENDOR_VIEW");
//INSERT into target
PreparedStatement ins = targetCon.prepareStatement(
"INSERT INTO VENDOR(VENDOR_NUMBER, "
+ "VENDOR_NAME, "
+ "INSTIME) VALUES (?,?,?)");
//Perform select / open Cursor
ResultSet rs = ps.executeQuery()) {
int vendornr = 0;
int MAXVENDOR = 1000;
while(rs.next()) {
//Set into INSERT the values we SELECTEd
ins.setString(1, rs.getString("VENDOR_NUMBER"));
ins.setString(2, rs.getString("VENDOR_NAME"));
ins.setTimestamp(3, rs.getTimestamp("MODIFIED_DATETIME"));
//Add to Batch (you could executeUpdate here but if you have los of rows...)
ins.addBatch();
if(++vendornr % MAXVENDOR == 0) {
ins.executeBatch();
}
}
//if number of rows was not aligned on MAXBATCH size...
ins.executeBatch();
}
}
看不清我在这里缺少什么。我有三列,供应商编号、供应商名称和修改日期时间。我知道拼写是正确的。这更像是“第二双眼睛”的情况。lol.再次感谢因为当Oracle server在sql server中使用MSSQL server驱动程序?数据导出工具时?@nikpon我实际上是在使用JDBC连接来连接Oracle。我只是使用sql server查看oracle数据库。对不起,这是我的错confusion@SeanLange . 我被告知不要使用SSI。相反,我被告知要使用SQLServerJAR文件,我不能把我的大脑完全放在被迫使用代码进行数据导入的想法上,除非这是一件正在进行的事情。即使如此,这似乎也不像一些查询那样复杂。如果在insert语句中不包含列,则该值将变为null,因此只需在insert语句中排除这些列即可。谢谢。我现在正在调查此事。谢谢你的帮助,简。我现在只有一个问题。我得到了这个错误:将nvarchar值转换为JDBC数据类型INTEGER时出错。我相信sql server变量列为nvarchar,而oracle数据库列为varchar。我正试图找出如何将其转换为干净的。有什么想法吗?所以现在我得到了这个错误:列名称货物\供应商\编号无效。因此,这是其中一列,它将被列为null,因为该列在源连接中不存在。以下是其取货地点的代码供应商编号。我知道我非常接近。我已经列出了上面的代码片段。关于这个有什么想法吗?谢谢,孩子,如果你不打算自己回答问题,你应该更新你的问题……在这一点上,我会因为花时间而有点恼火;-)有关建议的更改,请参见“我的答案中的编辑”。@Jan我将确保对您的评论表示赞同。很抱歉。所以现在我得到了太多值的错误。我相信这和时间戳有关。下面是我根据您修改代码的方式:while(rs.next()){ins.setString(1,rs.getString(“物料号”);ins.setString(2,rs.getString(“批次号”);ins.setString(3,rs.getString(“供应商批次号”);ins.setString(4,rs.getString(“供应商号”);ins.setString(5,rs.getString(“到期日”);ins.setTimestamp(6,rs.getTimestamp(“MODIFIED_DATETIME”);请编辑您的帖子,并包含insert语句。如果语句中的?数量与您设置的参数数量不匹配(本例中为6),则会出现此错误。或者,如果在insert INTO(a、b、c)值(a1、b1、c1、d2)中,则insert+“到期日”的值会多于列+“INSTIME将导致EXPIRATION\u DATEINSTIME-这将被解释为一列。“EXPIRATION\u DATE”+“INSTIME”应修复this@Jan.非常感谢。我犯了一个愚蠢的错误。还有一件事。我在上面列出的答案中又加了一个错误。