从SQLite迁移到Oracle

9

我有一个SQLite数据库在一个系统中,我需要将存储在SQLite中的数据提取到Oracle数据库中。我该怎么做?

4个回答

7
Oracle提供一种名为 Oracle Database Mobile Server(以前称为Oracle Database Lite)的产品,它允许您在SQLite和Oracle数据库之间进行同步。它提供可扩展的双向同步、模式映射、安全等功能。移动服务器支持同步和异步数据同步。如果这不仅仅是一次性导出,而且您需要保持SQLite和Oracle数据库同步,那么这是一个很好的工具!
免责声明:我是Oracle Database Mobile Server的产品经理之一,所以我有点偏见。然而,Mobile Server确实是一个很好的工具,可以用来保持您的SQLite(或Berkeley DB)和Oracle数据库同步。

0
你需要将SQLite转换为文本文件(格式不确定),然后使用Oracle从文本中加载数据库(来源是http://www.orafaq.com/wiki/SQLite)。你可以使用SQLite交互式shell的.dump命令将其转储到文本文件中(有关语法,请参见文档)。

0

SQL Loader是一个实用程序,它可以读取分隔符文本文件并将其导入Oracle数据库。您需要映射每个列从SQLite的扁平文件匹配到Oracle数据库中相应的列。这里有一个很好的FAQ,应该可以帮助您入门。


0
如果您是开发人员,可以开发一个应用程序来执行同步。您需要执行以下操作:

SELECT name FROM sqlite_master WHERE type='table'

获取表名,然后可以使用DROP TABLE tablename在Oracle中重新创建它们(假设SQLite将是权威的),并使用CREATE TABLE命令。获取每个表的列需要执行以下操作:

SELECT sql FROM sqlite_master WHERE type='table' and name='MyTable'

然后您需要解析结果。
string columnNames = sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').replace(/ [^,]+/g, '').split(',');
string[] columnArray = columnNames.Split(',');
foreach (string s in columnArray)
{
    // Add column to table using:
    // ALTER TABLE MyTable ADD COLUMN s NVARCHAR(250)
}

StringBuilder 可用于收集表名及其列以创建 INSERT 命令。要添加值,只需在循环遍历从初始查询返回的表名时,对每个表执行 SELECT * FROM MyTable 即可。您将迭代返回的数据表的行的列,并将值添加到 StringBuilder 中:

INSERT INTO MyTable ( + columnA、columnB 等 + ) VALUES ( datarow[0]、datarow[1] 等 + )

不完全像那样,你需要在循环中通过追加列名和数据来填充数据。你可以通过在上面的foreach循环中追加s来获取列名。然后使用一个foreach循环来设置每个列值,该循环会给你drData.ItemArray中的每个object obj。如果所有字段都是字符串类型,那么很容易,只需像下面一样将obj.ToString()添加到查询中每个列值的StringBuilder中。然后在收集每行的所有列值后运行查询。对于每一行,你需要使用一个新的StringBuilder - 在每个新行之前,它需要被重置为INSERT INTO MyTable ( + columnA、columnB等 + ) VALUES (,以便可以追加新的列值。

如果您有混合数据类型(例如DATEBLOB等),则需要在途中确定列类型,将其存储在列表或数组中,然后使用计数器确定该列表/数组插槽的索引并获取类型,以便知道如何将对象转换为Oracle可以使用的内容 - 无论是仅将to_date()添加到结果中进行格式化日期(因为SQLite将这些存储为具有格式yyyy-MM-dd HH:mm:ss的日期字符串),还是将其添加到OracleParameter中用于BLOB,并将其发送到RunOracleCommand函数。(下面没有涉及此问题。)
将所有这些放在一起得到以下结果:
string[] columnArray = null;
DataTable dtTableNames = GetSQLiteTable("SELECT name FROM sqlite_master WHERE type='table'");
if (dtTableNames != null && dtTableNames.Rows != null)
{
    if (dtTableNames.Rows.Count > 0)
    {
        // We have tables
        foreach (DataRow dr in dtTableNames.Rows)
        {
            // Do everything about this table here
            StringBuilder sb = new StringBuilder();
            sb.Append("INSERT INTO " + tableName + " ("); // we will collect column names here

            string tableName = dr["NAME"] != null ? dr["NAME"].ToString() : String.Empty;
            if (!String.IsNullOrEmpty(tableName))
            {
                RunOracleCommand("DROP TABLE " + tableName);
                RunOracleCommand("CREATE TABLE " + tableName);
            }

            DataTable dtColumnNames = GetSQLiteTable("SELECT sql FROM sqlite_master WHERE type='table' AND name='"+tableName+"'");
            if (dtColumnNames != null && dtColumnNames.Rows != null)
            {
                 if (dtColumnNames.Rows.Count > 0)
                 {
                     // We have columns
                     foreach (DataRow drCol in dtTableNames.Rows)
                     {
                          string sql = drCol["SQL"] != null ? drCol["SQL"].ToString() : String.Empty;
                          if (!String.IsNullOrEmpty(sql))
                          {
                              string columnNames = sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').replace(/ [^,]+/g, '').split(',');
                              columnArray = columnNames.Split(',');
                              foreach (string s in columnArray)
                              {
                                  // Add column to table using:
                                  RunOracleCommand("ALTER TABLE " + tableName + " ADD COLUMN " + s + " NVARCHAR(250)"); // can hard-code like this or use logic to determine the datatype/column width
                                  sb.Append("'" + s + "',");
                              }
                              sb.TrimEnd(",");
                              sb.Append(") VALUES (");
                          }
                      }
                  }
             }

            // Get SQLite Table data for insertion to Oracle
            DataTable dtTableData = GetSQLiteTable("SELECT * FROM " + tableName);
            if (dtTableData != null && dtTableData.Rows != null)
            {
                 if (dtTableData.Rows.Count > 0)
                 {
                     // We have data
                     foreach (DataRow drData in dtTableData.Rows)
                     {
                         StringBuilder sbRow = sb; // resets to baseline for each row
                         foreach (object obj in drData.ItemArray)
                         {
                             // This is simplistic and assumes you have string data for an NVARCHAR field
                             sbRow.Append("'" + obj.ToString() + "',");
                         }
                         sbRow.TrimEnd(",");
                         sbRow.Append(")");
                         RunOracleCommand(sbRow.ToString());
                     }
                 }
            }
        }
    }
}

所有这些都假定您有一个RunOracleCommand()无返回值函数,可以接受 SQL 命令并将其针对 Oracle DB 运行,以及一个GetSQLiteTable()函数,通过传递 SQL 命令可以从您的 SQLite DB 返回 DataTable。

请注意,此代码未经测试,因为我直接在此帖子中编写了它,但它基于我编写的用于将 Oracle 同步为 SQLite 的代码,已经过测试并且有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接