在将列表值从 C# 传输到 sqlite 时遇到问题
本文关键字:sqlite 遇到 问题 传输 列表 | 更新日期: 2023-09-27 18:37:18
BG 信息:开始者 创建一个桌面应用程序,该应用程序从文本文件中的列中读取值,然后解析它们。我设法将文本文件中的每个值存储到 3 个列表中(3 个列表,因为每个列表代表文件的一部分)。我现在计划将这些列表值加载到 sqlite 数据库中。这就是问题所在。
错误消息: 当我尝试传输列表值时,代码的 sqlite 部分会发生"接近"[i]"语法错误"。具体来说,这部分(它位于下面的代码段中的第三部分)
sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (list[i], list[i+1], list[i+2]);";
代码 导致重要部分:(这并不重要,只是为了任何需要它的 bg 信息,我在下面突出显示了重要的代码段)
namespace WindowsFormsApplication1
public partial class Form1 : Form
{
string[] val = new string[10];
string[] val2 = new string[6];
string[] val3 = new string[7];
string[] values = new string[1000];
List<string> list = new List<string>();
List<string> list2 = new List<string>();
List<string> list3 = new List<string>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
// Reading/Inputing column values
OpenFileDialog ofd = new OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
// Data Reading from section 1.
/*string[] lines = File.ReadAllLines(ofd.FileName).Skip(8).ToArray();
textBox1.Lines = lines;
*/
string[] fileLines = File.ReadAllLines(ofd.FileName);
// Import table values from Section 1: from Seq# to YYYY-MM
string[] section1 = fileLines.SkipWhile(line => !line.Contains("Seq#")).TakeWhile(line => !line.Contains("Total Records")).Where(line => Regex.IsMatch(line, @"['s|'d]{4}'d")).Select(line => line.PadRight(198)).ToArray();
int[] pos = new int[10] { 0, 6, 18, 47, 53,57, 61, 68, 82, 97 }; //setlen&pos to read specific colmn vals
int[] len = new int[10] { 6, 12, 29, 6 , 4, 4, 7, 14, 15, 6 }; // only doing 3 columns right now
只需用列值填充列表:(这部分工作正常)
foreach (string line in section1)
{
//if (line.StartsWith("0")) break;
for (int j = 0; j < 10; j++) // 3 columns
{
val[j] = line.Substring(pos[j], len[j]).Trim(); // each column value in row add to array
list.Add(val[j]); // column values stored in list
}
}
重要部分:SQLite连接(此处发生错误)**
private void button4_Click(object sender, EventArgs e)
{
// [snip] - As C# is purely object-oriented the following lines must be put into a class:
// We use these three SQLite objects:
SQLiteConnection sqlite_conn;
SQLiteCommand sqlite_cmd;
// create a new database connection:
sqlite_conn = new SQLiteConnection("Data Source=database.db;Version=3;New=True;Compress=True;");
// open the connection:
sqlite_conn.Open();
// create a new SQL command:
sqlite_cmd = sqlite_conn.CreateCommand();
// Let the SQLiteCommand object know our SQL-Query:
sqlite_cmd.CommandText = "CREATE TABLE table1 (Seq integer primary key, Field integer , Description integer );";
// Now lets execute the SQL ;D
sqlite_cmd.ExecuteNonQuery();
for (int i = 0; i < 500; i+=3)
{
// Lets insert something into our new table:
sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (list[i], list[i+1], list[i+2]);"; THIS IS WHERE PROBLEM OCCURS!
// And execute this again ;D
sqlite_cmd.ExecuteNonQuery();
}
// We are ready, now lets cleanup and close our connection:
sqlite_conn.Close();
}
不能传递将变量嵌入到 sql 字符串中。
这样,它们就变成了文字,不能用作整数字段的值。
需要使用参数化查询
sqlite_cmd.CommandText = "INSERT INTO table1 (Seq, Field, Description) VALUES (@p1, @p2, @p3)";
sqlite_cmd.Parameters.AddWithValue("@p1", 0); // dummy initial values
sqlite_cmd.Parameters.AddWithValue("@p2", 0);
sqlite_cmd.Parameters.AddWithValue("@p3", 0);
for (int i = 0; i < 500; i+=3)
{
sqlite_cmd.Parameters["@p1"].Value = Convert.ToInt32(list[i]);
sqlite_cmd.Parameters["@p2"].Value = Convert.ToInt32(list[i+1]);
sqlite_cmd.Parameters["@p3"].Value = Convert.ToInt32(list[i+2]); // Description as Integer ??
sqlite_cmd.ExecuteNonQuery();
}
在此代码中,占位符@p1、@p2 和 @p3 表示将由循环内相应值替换的参数。在进入循环之前,命令参数集合将使用对应于三个占位符的三个参数和一个虚拟初始值进行初始化。在循环中,每个参数都接收要从列表变量插入的实际值。
话虽如此,您在上面的代码中还有其他问题。
for (int j = 0; j < 10; j++) // 3 columns
此行循环用于 10 个项目而不是 9 个项目(0 到 9 是 10 个元素)
用于提供用于在数据库中插入值的参数的变量list
包含字符串而不是整数。但是创建表的代码定义了三列整数数据类型。现在不清楚您在这些列中存储了哪些数据,因为其中一个列被称为Description
几乎不是一个数字。
编辑 从您的评论来看,您似乎有一个相当旧版本的 sqlite 提供程序。
在这种情况下,应生成一个参数并将其添加到集合中。
sqlite_cmd.Parameters.Add(new SQLiteParameter("@p1", SqlDbType.Integer));