You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用批量更新MySQL数据库多行数据失败求助

Flutter批量更新MySQL多行数据失败问题解决

问题概述

在Flutter应用中尝试批量更新MySQL数据库多行数据时失败,触发SQL语法错误。

错误信息

MySqlException (错误码1064 (42000)): SQL语法有误;请查阅对应MySQL服务器版本的手册,了解在'? WHERE doc = ? AND sku = ?'附近使用正确语法的方法。

相关代码

DocPage业务代码

import 'package:cedi/data/connect.dart';
import 'package:flutter/material.dart';

class DocPage extends StatefulWidget {
  const DocPage({super.key});

  @override
  State<DocPage> createState() => _DocPageState();
}

class _DocPageState extends State<DocPage> {
  static List<DocsPickers> _docs = [];

  List docs = [
    {
      "qty": "400,0000",
      "date": "2023-07-24 07:43:00",
      "doc": "5275",
      "picker": "51",
      "sku": "VS100511",
      "cont": "25J2"
    },
    {
      "qty": "1152,0000",
      "date": "2023-07-24 08:04:00",
      "doc": "5275",
      "picker": "51",
      "sku": "VS100512",
      "cont": "25J2"
    }
  ];

  Future<void> _dataDocs() async {
    final db = Database();
    await db.connect();

    for (var _doc in docs) {
      final date = DateTime.parse(_doc["date"]);
      final doc = _doc["doc"];
      final sku = _doc["sku"];

      final results = await db.query(
        'UPDATE table1 SET date = ? WHERE doc = ? AND sku = ?',
        [date.toIso8601String(), doc, sku],
      );

      // ignore: avoid_print
      print('Updated rows: ${results.affectedRows}');
    }

    await db.close();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _dataDocs();
        },
      ),
      appBar: AppBar(),
    );
  }
}

class DocsPickers {
  String? sku;
  DateTime? date;
  int? doc;
  double? qty;

  DocsPickers({required this.sku, required this.doc, this.date, this.qty});
}

Database连接工具类代码

import 'package:mysql1/mysql1.dart';

class Database {
  late MySqlConnection _connection;

  Future<void> connect() async {
    _connection = await MySqlConnection.connect(
      ConnectionSettings(
        host: 'host',
        port: 3306,
        user: 'user',
        password: 'password',
        db: 'db',
      ),
    );
  }

  Future<Results> query(String sql, List<Object> list) async {
    return _connection.query(sql);
  }

  Future<void> close() async {
    await _connection.close();
  }
}

问题原因

Database类中的query方法接收了参数列表list,但并未将其传递给底层的_connection.query方法。导致SQL语句中的占位符?没有被实际参数替换,直接发送到MySQL服务器,触发语法错误。

修复方案

修改Database类的query方法,将参数列表传递给底层的query调用:

Future<Results> query(String sql, List<Object> list) async {
  return _connection.query(sql, list);
}

优化建议

如果需要批量更新大量数据,建议使用事务包裹所有更新操作,确保数据一致性的同时提升执行效率:

Future<void> _dataDocs() async {
  final db = Database();
  await db.connect();

  // 用事务包裹批量更新
  await db._connection.transaction((tx) async {
    for (var _doc in docs) {
      final date = DateTime.parse(_doc["date"]);
      final doc = _doc["doc"];
      final sku = _doc["sku"];

      final results = await tx.query(
        'UPDATE table1 SET date = ? WHERE doc = ? AND sku = ?',
        [date.toIso8601String(), doc, sku],
      );

      print('Updated rows: ${results.affectedRows}');
    }
  });

  await db.close();
}

注:若要避免直接访问私有成员_connection,可在Database类中新增事务封装方法。

内容的提问来源于stack exchange,提问作者Gekyo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:35:11