如何用 flutter 在 sqflite 中更新 table
how to update table in sqflite with flutter
当我尝试用 id 更新 table 时,什么都不会发生。我没有收到任何错误,我也不知道为什么会这样。
首先,我尝试从字段中获取所有数据,然后如果所有字段都有值,则创建 User 对象并传递给更新方法 table。
我从上一个屏幕获得了 id 并从字段中获得了其他数据。
当我检查时,我在 CompleteUserInformationScreen 的验证方法中拥有所有数据,我认为当我尝试使用 sqflite 调用更新方法时,某处发生了错误。
这是我的更新方法table:
Future<User> update(User user) async {
var dbClient = await db;
// return await dbClient.update(USER_TABLE, user.toMap(),
// where: '$NATIONAL_ID = ?', whereArgs: [user.nationalId]);
var res = await dbClient.rawQuery(
'UPDATE Customer SET $NAME = ${user.name}, $FAMILY = ${user.family}, $BIRTHDAY = ${user.birthday}, $MOBILE = ${user.mobile}, $NATIONAL_ID = ${user.nationalId} WHERE id = ${user.id}');
if (res.length > 0) {
return new User.fromMap(res.first);
}
return null;
}
这是我的屏幕:
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:atlas_gen_demo/Animation/FadeAnimation.dart';
import 'package:flutter/services.dart';
import '../models/user.dart';
import 'package:flushbar/flushbar.dart';
import 'package:atlas_gen_demo/data/storage/db_helper.dart';
import 'package:atlas_gen_demo/screens/users_list_screen.dart';
class CompleteUserInformationScreen extends StatelessWidget {
static const routeName = '/complete-user-information';
final nameController = TextEditingController();
final familyController = TextEditingController();
final nationalIdController = TextEditingController();
final mobileController = TextEditingController();
var id;
var birthday;
validate(BuildContext ctx) async {
if (nameController.text != "" &&
familyController.text != "" &&
nationalIdController.text != "" &&
mobileController.text != "") {
final dbHelper = DBHelper();
print("useriddd: $id birthdayyyy: ${birthday.toString()}");
User user = await dbHelper.update(User(
id,
nameController.text,
familyController.text,
null,
null,
birthday,
mobileController.text,
nationalIdController.text));
if (user.username != "") {
navigateToUsersList(ctx);
}
} else {
// showFlushBar(ctx, "fault", "fill all fields");
}
}
void navigateToUsersList(BuildContext ctx) {
Navigator.of(ctx).pushNamed(
UsersListScreen.routeName,
);
}
void showFlushBar(BuildContext context, String title, String text) {
Flushbar(
padding: EdgeInsets.all(10),
borderRadius: 8,
backgroundGradient: LinearGradient(
colors: [Colors.purple.shade800, Colors.purpleAccent.shade700],
stops: [0.6, 1],
),
boxShadows: [
BoxShadow(
color: Colors.black,
offset: Offset(3, 3),
blurRadius: 3,
)
],
dismissDirection: FlushbarDismissDirection.HORIZONTAL,
forwardAnimationCurve: Curves.fastLinearToSlowEaseIn,
titleText: Text(
title,
style: TextStyle(fontFamily: 'mainBold', color: Colors.white),
),
messageText: Text(
text,
style: TextStyle(fontFamily: 'mainMedium', color: Colors.white),
),
duration: Duration(seconds: 3),
).show(context);
}
@override
Widget build(BuildContext context) {
final userId = ModalRoute.of(context).settings.arguments;
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 250,
margin: EdgeInsets.only(top: 50),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/complete_profile.png'),
fit: BoxFit.fill,
),
),
),
Positioned(
child: FadeAnimation(
1.8,
InkWell(
child: Container(
margin: EdgeInsets.only(top: 10),
child: Center(
child: Text(
"Complete data",
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(143, 148, 251, 1),
fontSize: 20,
fontWeight: FontWeight.bold,
fontFamily: 'persianBold',
),
),
),
),
)),
),
Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(143, 148, 251, .2),
blurRadius: 20.0,
offset: Offset(0, 10))
],
),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: nameController,
textDirection: TextDirection.rtl,
textAlign: TextAlign.right,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "name",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: familyController,
textAlign: TextAlign.right,
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "family",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: nationalIdController,
textAlign: TextAlign.right,
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "national code",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: mobileController,
textAlign: TextAlign.right,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly
],
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "09123456789",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
FlatButton(
onPressed: () {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(1250, 1, 1),
maxTime: DateTime(1450, 12, 31),
onChanged: (date) {
print('change $date');
}, onConfirm: (date) {
birthday = date;
print('confirm $date');
},
currentTime: DateTime.now(),
locale: LocaleType.en);
},
child: Text(
'birthday',
)),
],
),
),
SizedBox(
height: 30,
),
FadeAnimation(
2,
InkWell(
onTap: () => {
// print(
// "useriddd: $userId birthdayyyy: ${birthday.toString()}"),
id = userId,
validate(context),
},
child: Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color.fromRGBO(143, 148, 251, .4),
Color.fromRGBO(143, 148, 251, .8),
],
),
),
child: Center(
child: Text(
"Complete data",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'persianBold',
fontSize: 18,
),
),
),
),
),
),
SizedBox(
height: 20,
),
],
),
)
],
),
),
),
);
}
}
编辑:
在代码中做了一些更改后我得到了这个错误:
Error Code : 1 (SQLITE_ERROR)
E/flutter (18587): Caused By : SQL(query) error or missing database.
E/flutter (18587): (near "00": syntax error (code 1): , while compiling: UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1})
E/flutter (18587): #################################################################) sql 'UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1}' args []}
更新代码:
Future<User> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
var res = await dbClient.rawQuery(
'UPDATE $USER_TABLE SET $NAME = $name, $FAMILY = $family, $BIRTHDAY = $birthday, $MOBILE = $mobile, $NATIONAL_ID = $nationalId WHERE id = $id');
if (res.length > 0) {
return new User.fromMap(res.first);
}
return null;
}
在我的屏幕上:
dbHelper.update(
id.toString(),
nameController.text,
familyController.text,
birthday.toString(),
mobileController.text,
nationalIdController.text);
navigateToUsersList(ctx);
编辑编号 2:
我认为我们只需要再执行一步即可:
我对数据库助手中的更新方法进行了新更改:
Future<int> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
return await dbClient.rawUpdate(
'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
}
当我尝试为 where 部分添加 Id 时出现此错误:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Invalid radix-10 number (at character 1)
E/flutter (21459): {id: 2}
但是如果我硬编码 id 例如 where $ID = 2
一切正常。我该如何解决这个问题?为什么在 id 旁边添加 {}?以及我必须如何删除它
我用这个 article 来实现我的数据库。在那里您可以找到与数据库交互所需的所有东西。
这对你有用,你只需要在用户中实现 "toMap" 方法 class:
Future<void> update(User user) async {
final dbClient = await database;
var res = await db.update("Customer", user.toMap(),
where: "id = ?", whereArgs: [user.id]);
return res;
}
经过一番搜索和尝试,我找到了解决方案:
db_helper中的更新方法:
Future<int> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
return await dbClient.rawUpdate(
'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
}
并在屏幕中验证方法:
validate(BuildContext ctx) async {
if (nameController.text != "" &&
familyController.text != "" &&
nationalIdController.text != "" &&
mobileController.text != "") {
final dbHelper = DBHelper();
dbHelper.update(
id.toString(),
nameController.text,
familyController.text,
birthday.toString(),
mobileController.text,
nationalIdController.text);
navigateToUsersList(ctx);
} else {
showFlushBar(ctx, "error", "Please fill all fields");
}
}
一种在 SQLite 数据库中更新 table 的简单方法。
- 这是我的 table
id
URL
SwiperList 是我的 table 名字
Id是自增主键属性
URL是简单的文本值
Future<int> update(String id, String url) async {
final db = await database;
return await db.rawUpdate(
'UPDATE SwiperList SET url = $url WHERE id = ${int.parse(id)}');
}
您可以根据自己的需求实现。
当我尝试用 id 更新 table 时,什么都不会发生。我没有收到任何错误,我也不知道为什么会这样。 首先,我尝试从字段中获取所有数据,然后如果所有字段都有值,则创建 User 对象并传递给更新方法 table。 我从上一个屏幕获得了 id 并从字段中获得了其他数据。 当我检查时,我在 CompleteUserInformationScreen 的验证方法中拥有所有数据,我认为当我尝试使用 sqflite 调用更新方法时,某处发生了错误。
这是我的更新方法table:
Future<User> update(User user) async {
var dbClient = await db;
// return await dbClient.update(USER_TABLE, user.toMap(),
// where: '$NATIONAL_ID = ?', whereArgs: [user.nationalId]);
var res = await dbClient.rawQuery(
'UPDATE Customer SET $NAME = ${user.name}, $FAMILY = ${user.family}, $BIRTHDAY = ${user.birthday}, $MOBILE = ${user.mobile}, $NATIONAL_ID = ${user.nationalId} WHERE id = ${user.id}');
if (res.length > 0) {
return new User.fromMap(res.first);
}
return null;
}
这是我的屏幕:
import 'package:flutter/material.dart';
import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
import 'package:atlas_gen_demo/Animation/FadeAnimation.dart';
import 'package:flutter/services.dart';
import '../models/user.dart';
import 'package:flushbar/flushbar.dart';
import 'package:atlas_gen_demo/data/storage/db_helper.dart';
import 'package:atlas_gen_demo/screens/users_list_screen.dart';
class CompleteUserInformationScreen extends StatelessWidget {
static const routeName = '/complete-user-information';
final nameController = TextEditingController();
final familyController = TextEditingController();
final nationalIdController = TextEditingController();
final mobileController = TextEditingController();
var id;
var birthday;
validate(BuildContext ctx) async {
if (nameController.text != "" &&
familyController.text != "" &&
nationalIdController.text != "" &&
mobileController.text != "") {
final dbHelper = DBHelper();
print("useriddd: $id birthdayyyy: ${birthday.toString()}");
User user = await dbHelper.update(User(
id,
nameController.text,
familyController.text,
null,
null,
birthday,
mobileController.text,
nationalIdController.text));
if (user.username != "") {
navigateToUsersList(ctx);
}
} else {
// showFlushBar(ctx, "fault", "fill all fields");
}
}
void navigateToUsersList(BuildContext ctx) {
Navigator.of(ctx).pushNamed(
UsersListScreen.routeName,
);
}
void showFlushBar(BuildContext context, String title, String text) {
Flushbar(
padding: EdgeInsets.all(10),
borderRadius: 8,
backgroundGradient: LinearGradient(
colors: [Colors.purple.shade800, Colors.purpleAccent.shade700],
stops: [0.6, 1],
),
boxShadows: [
BoxShadow(
color: Colors.black,
offset: Offset(3, 3),
blurRadius: 3,
)
],
dismissDirection: FlushbarDismissDirection.HORIZONTAL,
forwardAnimationCurve: Curves.fastLinearToSlowEaseIn,
titleText: Text(
title,
style: TextStyle(fontFamily: 'mainBold', color: Colors.white),
),
messageText: Text(
text,
style: TextStyle(fontFamily: 'mainMedium', color: Colors.white),
),
duration: Duration(seconds: 3),
).show(context);
}
@override
Widget build(BuildContext context) {
final userId = ModalRoute.of(context).settings.arguments;
return Scaffold(
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 250,
margin: EdgeInsets.only(top: 50),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/complete_profile.png'),
fit: BoxFit.fill,
),
),
),
Positioned(
child: FadeAnimation(
1.8,
InkWell(
child: Container(
margin: EdgeInsets.only(top: 10),
child: Center(
child: Text(
"Complete data",
textAlign: TextAlign.center,
style: TextStyle(
color: Color.fromRGBO(143, 148, 251, 1),
fontSize: 20,
fontWeight: FontWeight.bold,
fontFamily: 'persianBold',
),
),
),
),
)),
),
Padding(
padding: EdgeInsets.all(30.0),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(143, 148, 251, .2),
blurRadius: 20.0,
offset: Offset(0, 10))
],
),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: nameController,
textDirection: TextDirection.rtl,
textAlign: TextAlign.right,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "name",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: familyController,
textAlign: TextAlign.right,
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "family",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: nationalIdController,
textAlign: TextAlign.right,
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "national code",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
Container(
padding: EdgeInsets.all(8.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(color: Colors.grey[100]),
)),
child: TextFormField(
controller: mobileController,
textAlign: TextAlign.right,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly
],
textDirection: TextDirection.rtl,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "09123456789",
hintStyle: TextStyle(
color: Colors.grey[400],
fontFamily: 'persianMedium',
fontSize: 14,
),
),
),
),
FlatButton(
onPressed: () {
DatePicker.showDatePicker(context,
showTitleActions: true,
minTime: DateTime(1250, 1, 1),
maxTime: DateTime(1450, 12, 31),
onChanged: (date) {
print('change $date');
}, onConfirm: (date) {
birthday = date;
print('confirm $date');
},
currentTime: DateTime.now(),
locale: LocaleType.en);
},
child: Text(
'birthday',
)),
],
),
),
SizedBox(
height: 30,
),
FadeAnimation(
2,
InkWell(
onTap: () => {
// print(
// "useriddd: $userId birthdayyyy: ${birthday.toString()}"),
id = userId,
validate(context),
},
child: Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
colors: [
Color.fromRGBO(143, 148, 251, .4),
Color.fromRGBO(143, 148, 251, .8),
],
),
),
child: Center(
child: Text(
"Complete data",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontFamily: 'persianBold',
fontSize: 18,
),
),
),
),
),
),
SizedBox(
height: 20,
),
],
),
)
],
),
),
),
);
}
}
编辑:
在代码中做了一些更改后我得到了这个错误:
Error Code : 1 (SQLITE_ERROR)
E/flutter (18587): Caused By : SQL(query) error or missing database.
E/flutter (18587): (near "00": syntax error (code 1): , while compiling: UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1})
E/flutter (18587): #################################################################) sql 'UPDATE User SET name = mehrdad, family = dolat, birthday = 1450-12-31 00:00:00.000, mobile = 0936, nationalId = 001 WHERE id = {id: 1}' args []}
更新代码:
Future<User> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
var res = await dbClient.rawQuery(
'UPDATE $USER_TABLE SET $NAME = $name, $FAMILY = $family, $BIRTHDAY = $birthday, $MOBILE = $mobile, $NATIONAL_ID = $nationalId WHERE id = $id');
if (res.length > 0) {
return new User.fromMap(res.first);
}
return null;
}
在我的屏幕上:
dbHelper.update(
id.toString(),
nameController.text,
familyController.text,
birthday.toString(),
mobileController.text,
nationalIdController.text);
navigateToUsersList(ctx);
编辑编号 2:
我认为我们只需要再执行一步即可:
我对数据库助手中的更新方法进行了新更改:
Future<int> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
return await dbClient.rawUpdate(
'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
}
当我尝试为 where 部分添加 Id 时出现此错误:
[ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: FormatException: Invalid radix-10 number (at character 1)
E/flutter (21459): {id: 2}
但是如果我硬编码 id 例如 where $ID = 2
一切正常。我该如何解决这个问题?为什么在 id 旁边添加 {}?以及我必须如何删除它
我用这个 article 来实现我的数据库。在那里您可以找到与数据库交互所需的所有东西。
这对你有用,你只需要在用户中实现 "toMap" 方法 class:
Future<void> update(User user) async {
final dbClient = await database;
var res = await db.update("Customer", user.toMap(),
where: "id = ?", whereArgs: [user.id]);
return res;
}
经过一番搜索和尝试,我找到了解决方案:
db_helper中的更新方法:
Future<int> update(String id, String name, String family, String birthday,
String mobile, String nationalId) async {
var dbClient = await db;
return await dbClient.rawUpdate(
'UPDATE $USER_TABLE SET $NAME = \'$name\', $FAMILY = \'$family\' ,$BIRTHDAY = \'$birthday\', $MOBILE = \'$mobile\' , $NATIONAL_ID = \'$nationalId\' WHERE $ID = ${int.parse(id)}');
}
并在屏幕中验证方法:
validate(BuildContext ctx) async {
if (nameController.text != "" &&
familyController.text != "" &&
nationalIdController.text != "" &&
mobileController.text != "") {
final dbHelper = DBHelper();
dbHelper.update(
id.toString(),
nameController.text,
familyController.text,
birthday.toString(),
mobileController.text,
nationalIdController.text);
navigateToUsersList(ctx);
} else {
showFlushBar(ctx, "error", "Please fill all fields");
}
}
一种在 SQLite 数据库中更新 table 的简单方法。
- 这是我的 table
id | URL |
---|
SwiperList 是我的 table 名字
Id是自增主键属性
URL是简单的文本值
Future<int> update(String id, String url) async { final db = await database; return await db.rawUpdate( 'UPDATE SwiperList SET url = $url WHERE id = ${int.parse(id)}');
}
您可以根据自己的需求实现。