我试图从文本文件创建动态插入语句,只有SQLite。
到目前为止,我所做的是创建带有必要参数的SQL查询,在运行时添加这些参数,并尝试选择。
但是当我尝试cmd.ExecuteNonQuery();
捕获异常:SQL逻辑错误或缺少数据库 接近" @ 0":语法错误
using System;
using System.Data.SQLite;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data.SqlClient;
namespace TestApp
class Program
{
static void Main(string[] args)
{
//To store the index and column name in the file
Dictionary<int, string> Columns = new Dictionary<int, string>();
char[] delimiterChars = { '\t' };
string createQuery = @" create table if not exists products(id integer not null primary key, name text);
insert into products (name) values ('A');
insert into products (name) values ('B');
insert into products (name) values ('C');
insert into products (name) values ('D');
insert into products (name) values ('E');
insert into products (name) values ('F');
insert into products (name) values ('G');
create table if not exists orders(id integer, dt datetime, product_id integer, amount real);";
System.Data.SQLite.SQLiteConnection.CreateFile("myDB.db3");
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=myDB.db3")){
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn)){
conn.Open();
cmd.CommandText = createQuery;
cmd.ExecuteNonQuery();
string[] lines = System.IO.File.ReadAllLines(Directory.GetCurrentDirectory() + @"../../../App_Data/import.txt");
cmd.CommandText = "INSERT INTO orders (";
// Identify the column order from first row of the import file
string[] elements = lines[0].Split(delimiterChars);
for (int i = 0; i < elements.Length; i++)
{
Columns[i] = elements[i];
cmd.CommandText = cmd.CommandText + "@COLUMN" + i + ", ";
cmd.Parameters.AddWithValue("@COLUMN" + i, Columns[i]);
System.Console.WriteLine(i + " : " + Columns[i]);
}
cmd.CommandText = cmd.CommandText.Remove(cmd.CommandText.Length - 2);
cmd.CommandText = cmd.CommandText + ") VALUES (";
string temp = cmd.CommandText;
System.Console.WriteLine(cmd.CommandText);
System.Console.WriteLine("Contents of Import File.txt = ");
for (int i = 1; i < lines.Length; i++)
{
cmd.CommandText = temp;
elements = lines[i].Split(delimiterChars);
for (int j = 0; j < elements.Length; j++)
{
cmd.CommandText = cmd.CommandText + "@VALUE" + j + ", ";
cmd.Parameters.AddWithValue("@VALUE" + j, elements[j]);
}
cmd.CommandText = cmd.CommandText.Remove(cmd.CommandText.Length - 2);
cmd.CommandText = cmd.CommandText + ")";
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine("Caught exception: " + ex.Message);
}
Console.WriteLine(cmd.CommandText);
Console.WriteLine(lines[i]);
}
cmd.CommandText = "Select * from orders";
cmd.ExecuteNonQuery();
using (System.Data.SQLite.SQLiteDataReader reader = cmd.ExecuteReader()){
while (reader.Read())
{
Console.WriteLine(reader["ID"] + " | " + reader["dt"] + " | " + reader["product_id"] + " | " + reader["amount"]);
}
conn.Close();
}
}
}
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
}
}
我不确定我做错了什么?
import.txt文件由
组成id dt amount product_id
1 2017-02-01T10:01:12 343.33 1
2 2017-02-01T10:02:12 12 2
3 2017-03-01T10:03:12 344.3 1
4 2017-04-01T10:04:12 12 3
5 2017-05-01T10:05:12 66.5 1
6 2017-06-01T10:06:12 4
所有项目除以TAB
答案 0 :(得分:3)
列名称循环没用,因为您已经知道第一行执行的CREATE TABLE ORDERS命令中的列名。
顺便说一句,您不能使用参数来表示列的名称
在我所知的任何类型的数据库系统中都不允许这样做。
您可以安全地删除它,但请注意您已错误地声明了列顺序。在CREATE TABLE中你有
create table if not exists orders(
id integer, dt datetime, product_id integer, amount real
在文件中 product_id 是最后一列。所以你需要调整你的CREATE TABLE到你的文件
create table if not exists orders(
id integer, dt datetime, amount real, product_id integer;
接下来你的插入循环代码可以用这种方式重写(在解释时忽略可变数量的参数)
string baseQuery = "INSERT INTO orders (id, dt, amount, product_id ) VALUES(";
string[] lines = System.IO.File.ReadAllLines(@"e:\temp\orders.txt");
// Skip the first line
for (int i = 1; i < lines.Length; i++)
{
string[] elements = lines[i].Split(delimiterChars);
// Keep the parameter names in a list to get an easy way to
// concatenate them all together at the end of the loop
List<string> text = new List<string>();
for (int j = 0; j < elements.Length; j++)
{
text.Add("@VALUE" + j);
cmd.Parameters.AddWithValue("@VALUE" + j, elements[j]);
}
// Create the command text in a single shot
cmd.CommandText = baseQuery + string.Join(",", text) + ")";
try
{
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine("Caught exception: " + ex.Message);
}
}
考虑将您的数据库代码包含在这样的事务中,如下面由Alexander Petrov发布的链接所示
using (System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection("data source=myDB.db3"))
using (System.Data.SQLite.SQLiteCommand cmd = new System.Data.SQLite.SQLiteCommand(conn))
{
conn.Open();
using(SQLiteTransaction tr = conn.BeginTransaction())
{
cmd.Transaction = tr;
.....
for(....)
{
.....
}
tr.Commit();
}
}