我得到eroor
SqlfliteDatabaseException(DatabaseException(UNIQUE约束失败:products.id(code 1555 SQLITE_CONSTRAINT_PRIMARYKEY))sql 'INSERT INTO products(id,name,price,quantity)VALUES(?,?,?,?)' args [0,shoes,150000.0,1])
你能帮我吗
我的dtabasehelper
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqflite_crud/models/product.dart';
class DatabaseHelper {
DatabaseHelper._privateConstructor();
static final DatabaseHelper instance = DatabaseHelper._privateConstructor();
static Database? _database;
Future<Database> get database async {
_database ??= await _initDatabase();
return _database!;
}
Future<Database> _initDatabase() async {
String path = join(await getDatabasesPath(), 'kasir.db');
return await openDatabase(
path,
version: 1,
onCreate: _onCreate,
);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
price REAL,
quantity INTEGER
)
''');
}
Future<int> insertProduct(Product product) async {
Database db = await instance.database;
return await db.insert('products', product.toMap());
}
Future<List<Product>> getAllProducts() async {
Database db = await instance.database;
List<Map<String, dynamic>> maps = await db.query('products');
return List.generate(maps.length, (index) {
return Product.fromMap(maps[index]);
});
}
Future<int> updateProduct(Product product) async {
Database db = await instance.database;
return await db.update(
'products',
product.toMap(),
where: 'id = ?',
whereArgs: [product.id],
);
}
Future<int> deleteProduct(int id) async {
Database db = await instance.database;
return await db.delete(
'products',
where: 'id = ?',
whereArgs: [id],
);
}
}
我的班级
class Product {
int id;
String name;
double price;
int quantity;
Product({
required this.id,
required this.name,
required this.price,
required this.quantity,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'price': price,
'quantity': quantity,
};
}
static Product fromMap(Map<String, dynamic> map) {
return Product(
id: map['id'],
name: map['name'],
price: map['price'],
quantity: map['quantity'],
);
}
}
我的屏幕 dart
import 'package:flutter/material.dart';
import 'package:sqflite_crud/helpers/databasehelper.dart';
import 'package:sqflite_crud/models/product.dart';
import 'package:sqflite_crud/screens/user.dart';
import 'package:google_fonts/google_fonts.dart';
class CashierPage extends StatefulWidget {
@override
_CashierPageState createState() => _CashierPageState();
}
class _CashierPageState extends State<CashierPage> {
final _nameController = TextEditingController();
final _priceController = TextEditingController();
final _quantityController = TextEditingController();
final _formKey = GlobalKey<FormState>();
Future<List<Product>> _loadProducts() async {
return await DatabaseHelper.instance.getAllProducts();
}
void _logout() {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginPage()),
(Route<dynamic> route) => false,
);
}
void _addProduct() async {
if (_formKey.currentState!.validate()) {
Product product = Product(
id: 0, // ID 0 untuk penambahan baru
name: _nameController.text,
price: double.parse(_priceController.text),
quantity: int.parse(_quantityController.text),
);
await DatabaseHelper.instance.insertProduct(product);
_clearFields();
setState(() {});
}
}
void _deleteProduct(int id) async {
await DatabaseHelper.instance.deleteProduct(id);
setState(() {});
}
void _clearFields() {
_nameController.clear();
_priceController.clear();
_quantityController.clear();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Cashier App'),
actions: [
ElevatedButton(
onPressed: () {
_logout();
},
child: const Text(
'Logout',
style: TextStyle(color: Colors.white),
),
style: ElevatedButton.styleFrom(
primary: Colors.grey,
minimumSize: const Size(10, 40),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(50),
)),
textStyle: GoogleFonts.poppins(fontSize: 14),
),
),
],
),
body: FutureBuilder<List<Product>>(
future: _loadProducts(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Product> products = snapshot.data!;
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
Product product = products[index];
return ListTile(
title: Text(product.name),
subtitle: Text(
'Price: ${product.price}\nQuantity: ${product.quantity}'),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () => _deleteProduct(product.id),
),
);
},
);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Add Product'),
content: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
controller: _nameController,
decoration: InputDecoration(labelText: 'Name'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a name';
}
return null;
},
),
TextFormField(
controller: _priceController,
decoration: InputDecoration(labelText: 'Price'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a price';
}
return null;
},
),
TextFormField(
controller: _quantityController,
decoration: InputDecoration(labelText: 'Quantity'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter a quantity';
}
return null;
},
),
],
),
),
actions: [
TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_addProduct();
Navigator.of(context).pop();
}
},
child: Text('Add'),
),
TextButton(
onPressed: () {
_clearFields();
Navigator.of(context).pop();
},
child: Text('Cancel'),
),
],
);
},
);
},
child: Icon(Icons.add),
),
);
}
}
..........................................................................
1条答案
按热度按时间flvtvl501#
id列由于是PRIMARY KEY,因此隐式UNIQUE。您正在尝试插入一个id值已经存在的行(在给定示例中的值为0)。
可能的修复
您可以执行以下操作之一 (可能是粗体选项):-
INSERT INTO products (name,price,quantity) VALUES (?,?,?);
,因此只传递名称,价格和数量。*INSERT使用null而不是id,注意
int
不能为null。但是int?
是可以为空的。因此,定义为INTEGER PRIMARY KEY
(有或没有AUTOINCREMENT
)的列如果为null,将为该列生成一个值。AUTOINCREMENT
(参见https://www.sqlite.org/autoinc.html)int?
,那么您可以(我认为)id: null, // ID 0 untuk penambahan baru
INSERT INTO products (id,name,price,quantity) VALUES((?=-98989898)+(SELECT max(id) + 1 FROM products),?, ?,?);
--98989898
只是可以用来获得等于0的false的许多值之一。INSERT OR IGNORE ....
,在这种情况下,UNQIUE冲突将被忽略,行不会插入 (参见https://pub.dev/documentation/sqflite_common/latest/sql/ConflictAlgorithm.html)。OR IGNORE
INSERT OR REPLACE
,其中包含id的行将被替换 (参见https://pub.dev/documentation/sqflite_common/latest/sql/ConflictAlgorithm.html)