c#操作SQLite出现database is locked

qz2914650 2014-12-23 11:05:40
        private void button3_Click(object sender, EventArgs e)
{
string tm=""; //条码
string mc = ""; //名称
int cm = 0; //尺码
string ys = ""; //颜色



int sl = 0; //数量
int sj = 0; //售价
int cb = 0; //成本
int zdsj = 0; //最低售价,折扣价
tm = textBox3.Text;
mc = textBox4.Text;
cm = Convert.ToInt32(textBox5.Text);
ys = textBox6.Text;





sl = Convert.ToInt32(textBox10.Text);
sj = Convert.ToInt32(textBox11.Text);
cb = Convert.ToInt32(textBox12.Text);

// tm;mc;cm;ys;jj;lx;cl入数据库yf表,需要先判断是否有数据
// tm;sl(dj)入数据库sj表
// tm;sl入数据库kc表,同时计入rk表
// tm;sj入数据库jg表
conn.Open();
SQLiteCommand cmdcheck = conn.CreateCommand();
cmdcheck.CommandText = "select tm from yf where tm=" + tm;
SQLiteDataReader readercheck = cmdcheck.ExecuteReader();

if (readercheck.HasRows) //如果有条码,则update数据
{

SQLiteCommand cmdupdate = conn.CreateCommand();
cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm
+ ";" +
"update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm
+ ";" +
"update kc set kcl=kcl+" + sl + " where tm=" + tm
+ ";" +
"insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
int id=cmdupdate.ExecuteNonQuery();
//cmdupdate.Dispose();




////更新衣服表
//using(SQLiteCommand cmdupdate = conn.CreateCommand())
//{
// cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm;
// cmdupdate.ExecuteNonQuery();
//}

////更新售价表
//using (SQLiteCommand cmdsj = conn.CreateCommand())
//{
// cmdsj.CommandText = "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm;
// cmdsj.ExecuteNonQuery();
//}

////更新库存表
//using (SQLiteCommand cmdkc = conn.CreateCommand())
//{
// cmdkc.CommandText = "update kc set kcl=kcl+" + sl + " where tm=" + tm;
// cmdkc.ExecuteNonQuery();
//}

////插入入库表
//using (SQLiteCommand cmdrk = conn.CreateCommand())
//{
// cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
// cmdrk.ExecuteNonQuery();
//}

MessageBox.Show("更新入库成功", "更新入库");
}
else //如果没有查询到,则插入数据
{

//插入衣服表
SQLiteCommand cmdupdate = conn.CreateCommand();
cmdupdate.CommandText = "insert into yf(tm,mc,cm,ys) values('" + tm + "','" + mc + "','" + cm + "','" + ys + "')";
cmdupdate.ExecuteNonQuery();

//插入售价表
SQLiteCommand cmdsj = conn.CreateCommand();
cmdsj.CommandText = "insert into jg (tm,cb,dj) values ('"+tm+"','"+cb+"','"+sj+"')";
cmdsj.ExecuteNonQuery();

//插入库存表
SQLiteCommand cmdkc = conn.CreateCommand();
cmdkc.CommandText = "insert into kc values('"+tm+"','"+sl+"')";
cmdkc.ExecuteNonQuery();

//插入入库表
SQLiteCommand cmdrk = conn.CreateCommand();
cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
cmdrk.ExecuteNonQuery();


MessageBox.Show("新入库成功", "新入库");
}
try
{
conn.Close();
}
catch
{
MessageBox.Show("无法正常关闭数据库");
}

}


无语了,第一次执行时正常的,但是第二次执行就会出现database is locked
求解~
...全文
638 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuihui52121 2016-12-17
  • 打赏
  • 举报
回复
请问出现这个database is locked问题你是怎么解决的?
qz2914650 2014-12-23
  • 打赏
  • 举报
回复
引用 5 楼 dongxinxi 的回复:
可以用存储过程 建议cmdcheck.CommandText = "select tm from yf where tm=" + tm; 不要用dataReader,用conn.ExecuteScalar()就可以用一个conn了
我需要判断一下数据库中是否有这个条码的商品,所以需要看看是否有返回值!
qz2914650 2014-12-23
  • 打赏
  • 举报
回复
引用 2 楼 lc2737 的回复:
因为你cnn打开了没有关闭。

            string tm = "";          //条码
            string mc = "";        //名称
            int cm = 0;             //尺码
            string ys = "";         //颜色



            int sl = 0;             //数量
            int sj = 0;             //售价
            int cb = 0;             //成本
            int zdsj = 0;           //最低售价,折扣价
            tm = textBox3.Text;
            mc = textBox4.Text;
            cm = Convert.ToInt32(textBox5.Text);
            ys = textBox6.Text;





            sl = Convert.ToInt32(textBox10.Text);
            sj = Convert.ToInt32(textBox11.Text);
            cb = Convert.ToInt32(textBox12.Text);

            // tm;mc;cm;ys;jj;lx;cl入数据库yf表,需要先判断是否有数据
            // tm;sl(dj)入数据库sj表
            // tm;sl入数据库kc表,同时计入rk表
            // tm;sj入数据库jg表
            try
            {
                conn.Open();

                SQLiteCommand cmdcheck = conn.CreateCommand();
                cmdcheck.CommandText = "select tm from yf where tm=" + tm;
                SQLiteDataReader readercheck = cmdcheck.ExecuteReader();

                if (readercheck.HasRows)  //如果有条码,则update数据
                {

                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm
                        + ";" +
                        "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm
                        + ";" +
                        "update kc set kcl=kcl+" + sl + " where tm=" + tm
                        + ";" +
                        "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    int id = cmdupdate.ExecuteNonQuery();
                    //cmdupdate.Dispose();




                    ////更新衣服表
                    //using(SQLiteCommand cmdupdate = conn.CreateCommand())
                    //{
                    //    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm;                
                    //    cmdupdate.ExecuteNonQuery();
                    //}

                    ////更新售价表
                    //using (SQLiteCommand cmdsj = conn.CreateCommand())
                    //{
                    //    cmdsj.CommandText = "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm;
                    //    cmdsj.ExecuteNonQuery();
                    //}

                    ////更新库存表
                    //using (SQLiteCommand cmdkc = conn.CreateCommand())
                    //{
                    //    cmdkc.CommandText = "update kc set kcl=kcl+" + sl + " where tm=" + tm;
                    //    cmdkc.ExecuteNonQuery();
                    //}

                    ////插入入库表
                    //using (SQLiteCommand cmdrk = conn.CreateCommand())
                    //{
                    //    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    //    cmdrk.ExecuteNonQuery();
                    //}

                    MessageBox.Show("更新入库成功", "更新入库");
                }
                else  //如果没有查询到,则插入数据
                {

                    //插入衣服表
                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "insert into yf(tm,mc,cm,ys) values('" + tm + "','" + mc + "','" + cm + "','" + ys + "')";
                    cmdupdate.ExecuteNonQuery();

                    //插入售价表
                    SQLiteCommand cmdsj = conn.CreateCommand();
                    cmdsj.CommandText = "insert into  jg (tm,cb,dj) values ('" + tm + "','" + cb + "','" + sj + "')";
                    cmdsj.ExecuteNonQuery();

                    //插入库存表
                    SQLiteCommand cmdkc = conn.CreateCommand();
                    cmdkc.CommandText = "insert into kc values('" + tm + "','" + sl + "')";
                    cmdkc.ExecuteNonQuery();

                    //插入入库表
                    SQLiteCommand cmdrk = conn.CreateCommand();
                    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    cmdrk.ExecuteNonQuery();


                    MessageBox.Show("新入库成功", "新入库");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }
            finally
            {
                conn.Close();   
            }
关闭了,下边的try是我测试时加上的~~原来没有,直接conn.Close();
  • 打赏
  • 举报
回复
可以用存储过程 建议cmdcheck.CommandText = "select tm from yf where tm=" + tm; 不要用dataReader,用conn.ExecuteScalar()就可以用一个conn了
  • 打赏
  • 举报
回复
不是没有关闭,是dataReader这个对象是独占连接,并且只能向前读 所以你后面update时必须重新new一个conn using(readercheck) if (readercheck.HasRows) //如果有条码,则update数据 { using(conn = new Conn()) { SQLiteCommand cmdupdate = conn.CreateCommand(); ... } }
ajaxfeifei 2014-12-23
  • 打赏
  • 举报
回复
在执行复杂的数据库操作的时候最好加上Try,毕竟业务场景复杂,不要因为Try会降低一些性能而不用,稳定更重要。
ajaxfeifei 2014-12-23
  • 打赏
  • 举报
回复
因为你cnn打开了没有关闭。

            string tm = "";          //条码
            string mc = "";        //名称
            int cm = 0;             //尺码
            string ys = "";         //颜色



            int sl = 0;             //数量
            int sj = 0;             //售价
            int cb = 0;             //成本
            int zdsj = 0;           //最低售价,折扣价
            tm = textBox3.Text;
            mc = textBox4.Text;
            cm = Convert.ToInt32(textBox5.Text);
            ys = textBox6.Text;





            sl = Convert.ToInt32(textBox10.Text);
            sj = Convert.ToInt32(textBox11.Text);
            cb = Convert.ToInt32(textBox12.Text);

            // tm;mc;cm;ys;jj;lx;cl入数据库yf表,需要先判断是否有数据
            // tm;sl(dj)入数据库sj表
            // tm;sl入数据库kc表,同时计入rk表
            // tm;sj入数据库jg表
            try
            {
                conn.Open();

                SQLiteCommand cmdcheck = conn.CreateCommand();
                cmdcheck.CommandText = "select tm from yf where tm=" + tm;
                SQLiteDataReader readercheck = cmdcheck.ExecuteReader();

                if (readercheck.HasRows)  //如果有条码,则update数据
                {

                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm
                        + ";" +
                        "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm
                        + ";" +
                        "update kc set kcl=kcl+" + sl + " where tm=" + tm
                        + ";" +
                        "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    int id = cmdupdate.ExecuteNonQuery();
                    //cmdupdate.Dispose();




                    ////更新衣服表
                    //using(SQLiteCommand cmdupdate = conn.CreateCommand())
                    //{
                    //    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm;                
                    //    cmdupdate.ExecuteNonQuery();
                    //}

                    ////更新售价表
                    //using (SQLiteCommand cmdsj = conn.CreateCommand())
                    //{
                    //    cmdsj.CommandText = "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm;
                    //    cmdsj.ExecuteNonQuery();
                    //}

                    ////更新库存表
                    //using (SQLiteCommand cmdkc = conn.CreateCommand())
                    //{
                    //    cmdkc.CommandText = "update kc set kcl=kcl+" + sl + " where tm=" + tm;
                    //    cmdkc.ExecuteNonQuery();
                    //}

                    ////插入入库表
                    //using (SQLiteCommand cmdrk = conn.CreateCommand())
                    //{
                    //    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    //    cmdrk.ExecuteNonQuery();
                    //}

                    MessageBox.Show("更新入库成功", "更新入库");
                }
                else  //如果没有查询到,则插入数据
                {

                    //插入衣服表
                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "insert into yf(tm,mc,cm,ys) values('" + tm + "','" + mc + "','" + cm + "','" + ys + "')";
                    cmdupdate.ExecuteNonQuery();

                    //插入售价表
                    SQLiteCommand cmdsj = conn.CreateCommand();
                    cmdsj.CommandText = "insert into  jg (tm,cb,dj) values ('" + tm + "','" + cb + "','" + sj + "')";
                    cmdsj.ExecuteNonQuery();

                    //插入库存表
                    SQLiteCommand cmdkc = conn.CreateCommand();
                    cmdkc.CommandText = "insert into kc values('" + tm + "','" + sl + "')";
                    cmdkc.ExecuteNonQuery();

                    //插入入库表
                    SQLiteCommand cmdrk = conn.CreateCommand();
                    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    cmdrk.ExecuteNonQuery();


                    MessageBox.Show("新入库成功", "新入库");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }
            finally
            {
                conn.Close();   
            }
qz2914650 2014-12-23
  • 打赏
  • 举报
回复
异常信息 ************** 异常文本 ************** System.Data.SQLite.SQLiteException (0x80004005): database is locked database is locked 在 System.Data.SQLite.SQLite3.Step(SQLiteStatement stmt) 在 System.Data.SQLite.SQLiteDataReader.NextResult() 在 System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave) 在 System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior) 在 System.Data.SQLite.SQLiteCommand.ExecuteNonQuery(CommandBehavior behavior) 在 sqlite.Form1.button3_Click(Object sender, EventArgs e) 位置 D:\VS\sqlite\sqlite\sqlite\Form1.cs:行号 367 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase.WndProc(Message& m) 在 System.Windows.Forms.Button.WndProc(Message& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  • 打赏
  • 举报
回复
引用 12 楼 XuWei_XuWei 的回复:
sqllite是文件式数据库,每个请求处理,都是通过锁定整个文件来实现的,要是有一个处理忘记释放锁定了,下面的请求就挂了
事实不是这样的,sqlite没有这么垃圾,虽然是基于文件的,但连接上不代表文件就被独占访问了,这是两码事 低版本的sqlite支持共享(多)读锁(单)写,你可以自己在程序中控制这种并发写 高版本的现在已经支持内存映射了,换句话讲锁的粒度你可以通过内存偏移量划分得更细了
qz2914650 2014-12-23
  • 打赏
  • 举报
回复
引用 12 楼 XuWei_XuWei 的回复:
sqllite是文件式数据库,每个请求处理,都是通过锁定整个文件来实现的,要是有一个处理忘记释放锁定了,下面的请求就挂了
很不理解为什么第一次能都执行成功!
DO_大龄码农 2014-12-23
  • 打赏
  • 举报
回复
sqllite是文件式数据库,每个请求处理,都是通过锁定整个文件来实现的,要是有一个处理忘记释放锁定了,下面的请求就挂了
ajaxfeifei 2014-12-23
  • 打赏
  • 举报
回复
引用 6 楼 qz2914650 的回复:
[quote=引用 2 楼 lc2737 的回复:] 因为你cnn打开了没有关闭。

            string tm = "";          //条码
            string mc = "";        //名称
            int cm = 0;             //尺码
            string ys = "";         //颜色



            int sl = 0;             //数量
            int sj = 0;             //售价
            int cb = 0;             //成本
            int zdsj = 0;           //最低售价,折扣价
            tm = textBox3.Text;
            mc = textBox4.Text;
            cm = Convert.ToInt32(textBox5.Text);
            ys = textBox6.Text;





            sl = Convert.ToInt32(textBox10.Text);
            sj = Convert.ToInt32(textBox11.Text);
            cb = Convert.ToInt32(textBox12.Text);

            // tm;mc;cm;ys;jj;lx;cl入数据库yf表,需要先判断是否有数据
            // tm;sl(dj)入数据库sj表
            // tm;sl入数据库kc表,同时计入rk表
            // tm;sj入数据库jg表
            try
            {
                conn.Open();

                SQLiteCommand cmdcheck = conn.CreateCommand();
                cmdcheck.CommandText = "select tm from yf where tm=" + tm;
                SQLiteDataReader readercheck = cmdcheck.ExecuteReader();

                if (readercheck.HasRows)  //如果有条码,则update数据
                {

                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm
                        + ";" +
                        "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm
                        + ";" +
                        "update kc set kcl=kcl+" + sl + " where tm=" + tm
                        + ";" +
                        "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    int id = cmdupdate.ExecuteNonQuery();
                    //cmdupdate.Dispose();




                    ////更新衣服表
                    //using(SQLiteCommand cmdupdate = conn.CreateCommand())
                    //{
                    //    cmdupdate.CommandText = "update yf set mc='" + mc + "',cm='" + cm + "',ys='" + ys + "' where tm=" + tm;                
                    //    cmdupdate.ExecuteNonQuery();
                    //}

                    ////更新售价表
                    //using (SQLiteCommand cmdsj = conn.CreateCommand())
                    //{
                    //    cmdsj.CommandText = "update jg set dj=" + sj + ",cb=" + cb + ",zdsj=" + zdsj + " where tm=" + tm;
                    //    cmdsj.ExecuteNonQuery();
                    //}

                    ////更新库存表
                    //using (SQLiteCommand cmdkc = conn.CreateCommand())
                    //{
                    //    cmdkc.CommandText = "update kc set kcl=kcl+" + sl + " where tm=" + tm;
                    //    cmdkc.ExecuteNonQuery();
                    //}

                    ////插入入库表
                    //using (SQLiteCommand cmdrk = conn.CreateCommand())
                    //{
                    //    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    //    cmdrk.ExecuteNonQuery();
                    //}

                    MessageBox.Show("更新入库成功", "更新入库");
                }
                else  //如果没有查询到,则插入数据
                {

                    //插入衣服表
                    SQLiteCommand cmdupdate = conn.CreateCommand();
                    cmdupdate.CommandText = "insert into yf(tm,mc,cm,ys) values('" + tm + "','" + mc + "','" + cm + "','" + ys + "')";
                    cmdupdate.ExecuteNonQuery();

                    //插入售价表
                    SQLiteCommand cmdsj = conn.CreateCommand();
                    cmdsj.CommandText = "insert into  jg (tm,cb,dj) values ('" + tm + "','" + cb + "','" + sj + "')";
                    cmdsj.ExecuteNonQuery();

                    //插入库存表
                    SQLiteCommand cmdkc = conn.CreateCommand();
                    cmdkc.CommandText = "insert into kc values('" + tm + "','" + sl + "')";
                    cmdkc.ExecuteNonQuery();

                    //插入入库表
                    SQLiteCommand cmdrk = conn.CreateCommand();
                    cmdrk.CommandText = "insert into rk(tm,rkl,rksj) values ('" + tm + "','" + sl + "','" + DateTime.Now.ToString("yyyyMMdd") + "')";
                    cmdrk.ExecuteNonQuery();


                    MessageBox.Show("新入库成功", "新入库");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }
            finally
            {
                conn.Close();   
            }
关闭了,下边的try是我测试时加上的~~原来没有,直接conn.Close();[/quote] 没有细看到有DataReader
於黾 2014-12-23
  • 打赏
  • 举报
回复
conn和SQLiteDataReader都是数据库连接对象,都需要你释放 你应该用两层using分别把它们包起来,这样就不用自己考虑怎么去释放了
於黾 2014-12-23
  • 打赏
  • 举报
回复
SQLiteDataReader readercheck = cmdcheck.ExecuteReader(); 用using块包起来,值赋值给临时变量,后面去判断临时变量的值 不要占着茅坑不拉屎
qz2914650 2014-12-23
  • 打赏
  • 举报
回复
引用 4 楼 dongxinxi 的回复:
不是没有关闭,是dataReader这个对象是独占连接,并且只能向前读 所以你后面update时必须重新new一个conn using(readercheck) if (readercheck.HasRows) //如果有条码,则update数据 { using(conn = new Conn()) { SQLiteCommand cmdupdate = conn.CreateCommand(); ... } }
额,确实是这个问题,我添加额readercheck.Dispose();后正常了,但我非常不理解为什么第一次执行的时候不出现?

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧