【问题标题】:Inserting data from a WPF form into a MySQL database via C#通过 C# 将 WPF 表单中的数据插入 MySQL 数据库
【发布时间】:2013-07-31 02:45:48
【问题描述】:

我在通过 C# 将值插入 MySQL 数据库时遇到了一个特殊问题。

我有四个控件,我从 WPF 表单中收集数据;三个是文本框,一个是日期选择器。

连接数据库后,填写表格。我一直在使用以下值:

txtIdNumber: 1
dtpDateOfBirth = 7/30/2013 (today)
txtMenarcheAge = 14
txtSport1 = Soccer

这是它正在被清洗的代码:

if (MessageBox.Show("Are you sure you want to submit these changes to the database? Just making sure...", "", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                //database logic HERE.
                DateTime birthday = (DateTime)dtpDateOfBirth.SelectedDate;
                string birthdayString = birthday.ToString("yyyy-MM-dd");

                MySqlCommand cmd = new MySqlCommand();
                cmd.Connection = conn;

                Console.WriteLine(Convert.ToString(dtpDateOfBirth.SelectedDate));

                //check each box that MUST contain an entry, then submit it to the database if it's correct
                if (txtIdNumber.Text != "" && dtpDateOfBirth.SelectedDate != null)
                {                        
                    cmd.CommandText = "INSERT INTO TestSubject VALUES(NULL, @subjectId, @subjectDOB)";
                    cmd.Prepare();
                    cmd.Parameters.AddWithValue("@subjectId", txtIdNumber.Text);
                    cmd.Parameters.AddWithValue("@subjectDOB", "'" + birthdayString + "'");
                    Console.WriteLine(birthdayString);
                    Console.WriteLine(cmd.Parameters["@subjectId"].Value);
                    Console.WriteLine(cmd.Parameters["@subjectDOB"].Value);
                    cmd.ExecuteNonQuery();
                }
                else if (txtIdNumber.Text != "" && dtpDateOfBirth.SelectedDate != null && txtMenarcheAge.Text != "")
                {
                    cmd.CommandText = "INSERT INTO TestSubject VALUES(@subjectId, @subjectDOB, @subjectMenarche)";
                    cmd.Prepare();
                    cmd.Parameters.AddWithValue("@subjectId", txtIdNumber.Text);
                    cmd.Parameters.AddWithValue("@subjectDOB", birthdayString);
                    cmd.Parameters.AddWithValue("@subjectMenarche", txtMenarcheAge.Text);
                    cmd.ExecuteNonQuery();
                }
            }

首先,我将日期选择器中的日期时间转换为类似于 MySQL 使用的东西。然后,我将其转换为字符串。

接下来,我设置了必要的MySqlCommand对象,并将其Connection属性设置为conn,这是在另一个类中建立的。

然后是检查以确保表单有效。必须提供测试对象的 ID 号和生日,因此首先对其进行检查。这就是我们遇到麻烦的地方。我对 MySQL 中的预处理语句比较陌生,所以我使用了this 示例来让自己有方向感。在街区

cmd.CommandText = "INSERT INTO TestSubject VALUES(NULL, @subjectId, @subjectDOB)";
cmd.Prepare();
cmd.Parameters.AddWithValue("@subjectId", txtIdNumber.Text);
cmd.Parameters.AddWithValue("@subjectDOB", "'" + birthdayString + "'");
Console.WriteLine(birthdayString);
Console.WriteLine(cmd.Parameters["@subjectId"].Value);
cmd.ExecuteNonQuery();

我在运行时遇到以下异常:

MySql.Data.MySqlClient.MySqlException was unhandled


HResult=-2147467259
  Message=Column 'subjectId' cannot be null
  Source=MySql.Data
  ErrorCode=-2147467259
  Number=1048
  StackTrace:
       at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
       at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
       at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
       at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
       at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
       at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
       at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
       at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
       at mu_kinect_project_data_form.MainWindow.btnSubmitWholeForm_Click(Object sender, RoutedEventArgs e) in c:\Users\asm3kf.TIGERS\Documents\mu_kinect_project_data_form\mu_kinect_project_data_form\MainWindow.xaml.cs:line 315
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.Controls.Button.OnClick()
       at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
       at System.Windows.Input.InputManager.ProcessStagingArea()
       at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run()
       at mu_kinect_project_data_form.App.Main() in c:\Users\asm3kf.TIGERS\Documents\mu_kinect_project_data_form\mu_kinect_project_data_form\obj\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException:

我不确定subjectIdnull 的想法是从哪里来的。它正在接收输入。

编辑:添加 MySQL 脚本,因为这是拼图的一半。

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';

CREATE SCHEMA IF NOT EXISTS `kinect7` DEFAULT CHARACTER SET utf8 ;
USE `kinect7` ;

-- -----------------------------------------------------
-- Table `kinect7`.`TestSubject`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kinect7`.`TestSubject` (
  `subjectId` INT(11) NOT NULL ,
  `subjectDOB` DATE NOT NULL ,
  `subjectMenarche` DATE NULL DEFAULT NULL ,
  PRIMARY KEY (`subjectId`) ,
  UNIQUE INDEX `subjectId_UNIQUE` (`subjectId` ASC) )
ENGINE = InnoDB
COMMENT = '     ';


-- -----------------------------------------------------
-- Table `kinect7`.`SubjectInjury`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kinect7`.`SubjectInjury` (
  `injuryDate` DATE NOT NULL ,
  `injuryKnee` VARCHAR(5) NOT NULL ,
  `TestSubject_subjectId` INT(11) NOT NULL ,  
  `surgeryPerformed` VARCHAR(10) NULL,  
  PRIMARY KEY (`TestSubject_subjectId`, `injuryKnee`, `injuryDate`) ,
  CONSTRAINT `fk_PreviousInjury_TestSubject1`
    FOREIGN KEY (`TestSubject_subjectId` )
    REFERENCES `kinect7`.`TestSubject` (`subjectId` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `kinect7`.`SubjectJumps`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kinect7`.`SubjectJumps` (
  `jumpDate` DATETIME NOT NULL ,
  `rightAnkleRatio` DECIMAL(6,3) NULL DEFAULT NULL ,
  `leftAnkleRatio` DECIMAL(6,3) NULL DEFAULT NULL ,
  `rightKneeValgus` DECIMAL(6,3) NULL DEFAULT NULL ,
  `leftKneeValgus` DECIMAL(6,3) NULL DEFAULT NULL ,
  `rightKneeFlexion` DECIMAL(6,3) NULL DEFAULT NULL ,
  `leftKneeFlexion` DECIMAL(6,3) NULL DEFAULT NULL ,
  `testSubject_subjectId` INT(11) NOT NULL ,
  PRIMARY KEY (`jumpDate`, `testSubject_subjectId`) ,
  INDEX `fk_subjectJumps_testSubject_idx` (`testSubject_subjectId` ASC) ,
  CONSTRAINT `fk_subjectJumps_testSubject`
    FOREIGN KEY (`testSubject_subjectId` )
    REFERENCES `kinect7`.`TestSubject` (`subjectId` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;


-- -----------------------------------------------------
-- Table `kinect7`.`SubjectSports`
-- -----------------------------------------------------
CREATE  TABLE IF NOT EXISTS `kinect7`.`SubjectSports` (
  `sport` VARCHAR(10) NOT NULL ,
  `TestSubject_subjectId` INT(11) NOT NULL ,
  PRIMARY KEY (`TestSubject_subjectId`, `sport`) ,
  CONSTRAINT `fk_SubjectSports_TestSubject1`
    FOREIGN KEY (`TestSubject_subjectId` )
    REFERENCES `kinect7`.`TestSubject` (`subjectId` )
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;   

SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;

【问题讨论】:

  • 您的餐桌布局是什么?您将 SubjectId 和 DOB 插入这两个语句的不同列中。在一个中,SubjectId 是第二列,在另一个中是第一列。我的猜测是您的第一列是 subjectId 并且您插入的 null 导致了错误。
  • 对不起,当你们问的时候,实际上是试图在帖子中得到它......谢谢错误检查器......>:/
  • 1 - 从后面的代码中删除所有这些代码并创建一个合适的 ViewModel。 2 - 使用 ORM 并忘记所有这些 SQL 字符串混乱。
  • 是的,正如我推测的那样,这是你的问题。 subjectId 是 column1 并且您要在其中插入一个硬编码的空值。如果你听从 Will Eddin 的建议,你就会避免这个问题。

标签: c# mysql wpf ado.net mysql-connector


【解决方案1】:

要弄清楚错误到底发生在哪里有点困难,但您可能希望在 SQL 查询中定义列名:

cmd.CommandText = "INSERT INTO TestSubject (Subject,DOB) VALUES (@subjectId, @subjectDOB)";

这样,您不必为缺少的列显式传递 null,并且您可以确定每个值被分配到哪些列。

【讨论】:

  • 到目前为止有效。让我快速检查一下这些值是否正确匹配。向您展示当您按照说明操作时会发生什么...感谢 Oracle!
猜你喜欢
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
相关资源
最近更新 更多