UNIQUE约束失败:products.id(code 1555 SQLITE_CONSTRAINT_PRIMARYKEY))sql 'INSERT INTO products(id,name,price,quantity)VALUES(?,?,?,

j0pj023g  于 2023-05-23  发布在  SQLite
关注(0)|答案(1)|浏览(422)

我得到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),
      ),
    );
  }
}

..........................................................................

flvtvl50

flvtvl501#

  • 问题 *
    id列由于是PRIMARY KEY,因此隐式UNIQUE。您正在尝试插入一个id值已经存在的行(在给定示例中的值为0)。
    可能的修复

您可以执行以下操作之一 (可能是粗体选项):-

  • 使用一个唯一的值插入(这需要确定存在的id的值)。
  • INSERT,其中id的值不沿着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
  • 例如,如果idint?,那么您可以(我认为)id: null, // ID 0 untuk penambahan baru
  • INSERT使用一个表达式将0转换为一个唯一的值,例如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

相关问题