читать данные из sqlite в С#, а затем в sqlite

Воспроизводимый пример:

sqlite db test3.s3db имеет одну таблицу с именем «MathRec»:

name score
Bill 2
Mary 3
John 3

Код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SQLite;

namespace ConsoleApplication7

{
    class Program
    {
    static void Main(string[] args)
    {

        string fullPath = "C:\\Users\\Desktop\\dataset\\test3.s3db";
        SQLiteConnection conread = new SQLiteConnection("Data Source=" + fullPath);
        conread.Open();

        string selectSQL = "SELECT * FROM MathRec";
        SQLiteCommand selectCommand = new SQLiteCommand(selectSQL, conread);
        SQLiteDataReader dataReader = selectCommand.ExecuteReader();
        DataSet ds = new DataSet();
        DataTable dt = new DataTable("MathRec");
        dt.Load(dataReader);
        ds.Tables.Add(dt);



        // Create a table in the database to receive the information from the DataSet

        string fullPath2 = "C:\\Users\\\\Desktop\\dataset\\test4.s3db";
        SQLiteConnection conwrite = new SQLiteConnection("Data Source=" + fullPath2);
        conwrite.Open();
        SQLiteCommand cmd = new SQLiteCommand(conwrite);
        cmd.CommandText = "DROP TABLE IF EXISTS MathRec";
        cmd.ExecuteNonQuery();
        cmd.CommandText = "CREATE TABLE MathRec(name text , score integer)";
        cmd.ExecuteNonQuery();
        SQLiteDataAdapter adaptor = new SQLiteDataAdapter("SELECT * from MathRec", conwrite);
        adaptor.InsertCommand = new SQLiteCommand("INSERT INTO MathRec  VALUES(:name, :score)", conwrite);
        adaptor.InsertCommand.Parameters.Add("name", DbType.String, 0, "name");
        adaptor.InsertCommand.Parameters.Add("score", DbType.Int32, 0, "score");
        adaptor.Update(ds, "MathRec");



         }

    }
 }

Вопросы: В test4.s3db создается таблица MathRec с именами столбцов: name и socre, но таблица пуста, записи не вставлены.

Нужна помощь!

Пожалуйста, не спрашивайте меня, почему я просто копирую одну базу данных в другую, потому что я тестирую одну часть кода для более крупного проекта, где я буду выполнять вычисления для набора данных на среднем этапе в будущем.

Спасибо!


Чтобы упростить вопрос:

Это работает (используйте данные и адаптер для обновления исходной таблицы sqlite):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullPath = "C:\\Users\\data\\test.db";
            SQLiteConnection conread = new SQLiteConnection("Data Source=" + fullPath);
            conread.Open();


        SQLiteDataAdapter DB = new SQLiteDataAdapter("SELECT speed, dist FROM Cars2", conread);
        DataSet DS = new DataSet();

        DB.Fill(DS, "NewCars");


        object[] rowVals = new object[2];
        rowVals[0] = 10;
        rowVals[1] = 20;
        DS.Tables["NewCars"].Rows.Add(rowVals);


        DB.InsertCommand = new SQLiteCommand("INSERT INTO Cars2 (speed, dist)  
                                 " + " VALUES (:speed,  :dist)", conread);
        DB.InsertCommand.Parameters.Add("speed", DbType.Double, 0, "speed");
        DB.InsertCommand.Parameters.Add("dist", DbType.Double, 20, "dist");
        DB.Update(DS, "NewCars");



        }
    }
}

И это работает (создайте новую таблицу sqlite из старой):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullPath = "C:\\Users\\data\\test.db";
            SQLiteConnection conread = new SQLiteConnection("Data Source=" + fullPath);
            conread.Open();


        SQLiteCommand cmd = new SQLiteCommand(conread);
        cmd.CommandText = "DROP TABLE IF EXISTS Cars";
        cmd.ExecuteNonQuery();
        cmd.CommandText = "CREATE TABLE Cars (speed REAL , dist REAL)";
        cmd.ExecuteNonQuery();
        cmd.CommandText = "INSERT INTO Cars SELECT * from DS";
        cmd.ExecuteNonQuery();
        cmd.Dispose();
        }
    }
}

Но это то, что я хотел (используйте данные и адаптер для создания новой таблицы в sqlite) и не работает:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SQLite;
using System.Data;

namespace ConsoleApplication7
{
    class Program
    {
        static void Main(string[] args)
        {
            string fullPath = "C:\\Users\\data\\test.db";
            SQLiteConnection conread = new SQLiteConnection("Data Source=" + fullPath);
            conread.Open();
    SQLiteDataAdapter DB = new SQLiteDataAdapter("SELECT speed, dist FROM Cars2", conread);
    DataSet DS = new DataSet();

    DB.Fill(DS, "NewCars");


    object[] rowVals = new object[2];
    rowVals[0] = 10;
    rowVals[1] = 20;
    DS.Tables["NewCars"].Rows.Add(rowVals);


   SQLiteDataAdapter DB2 = new SQLiteDataAdapter("SELECT speed, dist FROM Cars3", conread);
    DB2.InsertCommand = new SQLiteCommand("INSERT INTO Cars3 (speed, dist)  
                        " + " VALUES (:speed,  :dist)", conread);
    DB2.InsertCommand.Parameters.Add("speed", DbType.Double, 0, "speed");
    DB2.InsertCommand.Parameters.Add("dist", DbType.Double, 20, "dist");
    DB2.Update(DS, "NewCars");


    }
}
}

Пожалуйста помоги!!!


person TongZZZ    schedule 22.04.2013    source источник
comment
Все, что я могу сказать, это то, что sqlite иногда может быть БОЛЬШОЙ болью   -  person FrostyFire    schedule 22.04.2013
comment
так что я должен забыть sqlite и просто пойти на SQLServer? каково ваше предложение тогда?   -  person TongZZZ    schedule 22.04.2013
comment
Обычно имя параметра должно включать любой специальный символ, например. @name или :name при добавлении параметра в коллекцию Parameters.   -  person Tim    schedule 22.04.2013
comment
Вы уверены, что SQLiteDataAdapter можно использовать для одновременного доступа к двум разным соединениям?   -  person CL.    schedule 22.04.2013
comment
@TongZZZ У меня его нет. Просто иногда говорю, что это большая боль. Я бы выбрал SQLServer, если бы мог себе это позволить.   -  person FrostyFire    schedule 23.04.2013


Ответы (2)


Я нашел ответ!

Adapter.Update можно использовать только для обновления исходной таблицы в базе данных, а не для сохранения таблицы данных в новой. Пожалуйста, обратитесь к теме для ответов:

Набор данных C# для доступа к БД

Ваше здоровье!

person TongZZZ    schedule 24.04.2013

Самый простой способ скопировать одну таблицу в другую базу данных — подключить вторую базу данных к первому соединению и напрямую скопировать данные:

ATTACH '...\test4.s3db' AS 'test4';
DROP TABLE IF EXISTS test4.MathRec;
CREATE TABLE test4.MathRec(name text , score integer);
INSERT INTO test4.MathRec SELECT * FROM MathRec;

Если вы хотите выполнять вычисления, вы можете сделать это в SQL, в операторе SELECT. Если нет, вы должны прочитать данные с помощью SELECT, а затем выполнить один оператор INSERT для каждой записываемой записи. (В этом случае вам не нужен ATTACH.)

person CL.    schedule 22.04.2013
comment
Спасибо за ваш ответ, теперь я решил использовать только одну базу данных, и само ваше предложение работает. Тем не менее, я действительно хочу вставить таблицу из DataTable в таблицу SQLite, а не из другой таблицы SQLite как INSERT INTO test4.MathRec SELECT * FROM MathRec;. Таким образом, я думаю, что мне нужно использовать адаптер SQLiteDataAdapter, и мне с ним пока не везет. - person TongZZZ; 23.04.2013