代码之家  ›  专栏  ›  技术社区  ›  PabloD2

在C#SQLite中将BLOB从旧数据库导入新数据库时出现问题

  •  0
  • PabloD2  · 技术社区  · 6 年前

    我在将旧数据库导入具有不同结构的新数据库时遇到了大问题。

    在旧版本中,我有:

    表:CHART\u数据

    CHART\u ID-整数,主键,自动递增

    CHART\u DATA-包含二进制文件的BLOB

    文件的十六进制视图示例:01000000630AC2BF332934BF79E08D43EFF13645

    从旧数据库中选择:

        sql = "SELECT hex(CHART_DATA) FROM CHART_DATA";
                SQLiteCommand select_hex = new SQLiteCommand(sql.ToString(), old_dbConnection);
                reader = select_hex.ExecuteReader();
        int i = 0;
        while (reader.Read())
                {
                    chart_hex[i] = reader[0].ToString();
                    i++;
                }
    

    当我尝试将其保存到新基地时,我遇到了许多问题:

    第一次尝试: 将字符串保存到BLOB列:

    for (int k = 0; k < count; k++)
            {
                SQLiteCommand command = new SQLiteCommand(sqlinsert.ToString(), new_dbConnection);
                command.CommandText = "INSERT INTO chart(chart_file) VALUES (@chart_file)";
                command.Parameters.AddWithValue("@chart_file", chart_hex[k]]);
            }
    

    结果是可预测的,列中的字符串值:((例如:01000000630AC2BF332934BF79E08D43EFF13645)

    第二次尝试: 另存为DbType。二进制的

    for (int k = 0; k < count; k++)
            {
                SQLiteCommand command = new SQLiteCommand(sqlinsert.ToString(), new_dbConnection);
                command.CommandText = "INSERT INTO chart(chart_file) VALUES (@chart_file)";
                 command.Parameters.Add("@chart_file", DbType.Binary, 20).Value = chart_hex[k];
            }
    

    相同结果:((字符串:01000000630AC2BF332934BF79E08D43EFF13645)

    第三次尝试: 字符串到字节的转换

     for (int k = 0; k < count; k++)
                {
                    SQLiteCommand command = new SQLiteCommand(sqlinsert.ToString(), new_dbConnection);
                    command.CommandText = "INSERT INTO chart(chart_file) VALUES (@chart_file)";
                    command.Parameters.Add("@chart_file", DbType.Binary, 20).Value = GetBytes(chart_hex[k]);
                    //command.Parameters.AddWithValue("@chart_file", GetBytes(chart_hex[k, 1])); //I also try this 
    
                }
    
                ...
    
                 static byte[] GetBytes(string str)
                {
                    byte[] bytes = new byte[str.Length * sizeof(char)];
                    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
                    return bytes;
                }
    

    结果是数据库中的BLOB对象出现问题。文件与原始文件不同:

    原件: 01000000630AC2BF332934BF79E08D43EFF13645

    在新数据库中:

    31003000300030003000300030003600
    33003000410043003200420046003300
    33003200390033003400420046003700
    39004500300038004400340033004500
    4600460031003300360034003500
    

    我已经想不出如何导入此表单旧DB了:(

    1 回复  |  直到 6 年前
        1
  •  0
  •   Mark Benningfield    6 年前

    如果不需要字符串,则不要选择字符串。将目标阵列更改为 object 数组,并在旧数据库中存储值时仅获取这些值。这假设BLOB数据实际上没有作为文本存储在旧数据库中。

    string sql = "SELECT CHART_DATA FROM CHART_DATA";
    SQLiteCommand select_hex = new SQLiteCommand(sql, old_dbConnection);
    reader = select_hex.ExecuteReader();
    int i = 0;
    while (reader.Read())
    {
      // chart_hex is changed to an object array, not a string array
      chart_hex[i] = reader[0];
      i++;
    }
    

    然后,只需插入对象值:

    for (int k = 0; k < count; k++)
    {
      SQLiteCommand command = new SQLiteCommand(new_dbConnection);
      command.CommandText = "INSERT INTO chart(chart_file) VALUES (@chart_file)";
      command.Parameters.AddWithValue("@chart_file", chart_hex[k]]);
    }
    

    这个 SQLiteParameter 类应在两个方向上将对象值映射到BLOB列关联,从而以相同的格式检索和存储数据。