【问题标题】:SQL and C# Error: Error on SQL procedure: Error converting data type nvarchar to datetime [duplicate]SQL 和 C# 错误:SQL 过程出错:将数据类型 nvarchar 转换为日期时间时出错 [重复]
【发布时间】:2020-06-04 02:46:59
【问题描述】:

我正在开发一个 SQL Server 数据库程序,它的界面上有 2 个dateTimePickers,用于选择 DOJ(加入日期)和 DOB(出生日期)。除了dateTimePickers,一切似乎都运行良好,它不断出现:

将 nvarchar 转换为日期时间时出错

我尝试将其更改为nvarchar(50)nvarchar(MAX),但随后出现了相同的错误。表单看起来像这样,还出现了错误:https://i.imgur.com/jEd69FM.png

这是 SQL Server 存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[StudentAdd]
    @FirstName varchar(50),
    @LastName varchar(50),
    @CourseEnrolled varchar(250),
    @Level int,
    @DOJ datetime,
    @DOB datetime
AS
    INSERT INTO tblStudent (First_Name, Last_Name, Course_Enrolled, Level, DOJ, DOB) 
    VALUES (@FirstName, @LastName, @CourseEnrolled, @Level, @DOJ, @DOB)

C#代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace final_assessment
{
    public partial class Form4 : Form
    {
        public Form4()
        {
            InitializeComponent();
        }

        string connectionString = "Data Source=DESKTOP-SQ1V840;Initial Catalog=UserRegistration;Integrated Security=True";

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                using (SqlConnection sqlCon = new SqlConnection(connectionString))
                {
                    sqlCon.Open();

                    using (SqlCommand sqlCmd = new SqlCommand("StudentAdd", sqlCon))
                    {
                        sqlCmd.CommandType = CommandType.StoredProcedure;

                        sqlCmd.Parameters.AddWithValue("@FirstName", textBox1.Text.Trim());
                        sqlCmd.Parameters.AddWithValue("@LastName", textBox2.Text.Trim());
                        sqlCmd.Parameters.AddWithValue("@CourseEnrolled", textBox3.Text.Trim());
                        sqlCmd.Parameters.AddWithValue("@Level", textBox4.Text.Trim());
                        sqlCmd.Parameters.AddWithValue("@DOJ", dateTimePicker1.Text.Trim());
                        sqlCmd.Parameters.AddWithValue("@DOB", dateTimePicker2.Text.Trim());

                        sqlCmd.ExecuteNonQuery();
                    }
                }

                MessageBox.Show("Registration successful");
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error in the SQL Server \"StudentAdd\" procedure: {ex.Message}");
            }
        }
    }
}

【问题讨论】:

  • 问题可能不是文本的长度,而是 datetimepicker 的 DateTime 的格式被格式化为不同于 SQL Server 预期的字符串。使用带有 SqlDbType.DateTime 的 SqlParameter 和来自 datetimepicker 控件的实际 DateTime 值。另见Can we stop using AddWithValue() already?
  • 那么我应该把代码放在哪里?我对这两个 cmets 感到很困惑,因为他们没有给我一个正确的真实答案,让我知道该怎么做
  • dateTimePicker1Value 属性吗?如果有,它的类型是什么?
  • 怀疑你想使用dateTimePicker1.Value而不是dateTimePicker1.Text.Trim()

标签: c# sql-server winforms


【解决方案1】:

您可以在 CSharp 中尝试以下代码。

using (SqlConnection openCon = new SqlConnection("Server=YourServerName;Database=YourDBName;Trusted_Connection=True;"))
{
    string saveStaff = "INSERT into test (a) VALUES (@dateValue)";

    using (SqlCommand querySaveStaff = new SqlCommand(saveStaff))
    {
        querySaveStaff.Connection = openCon;
         querySaveStaff.Parameters.Add("@dateValue", SqlDbType.DateTime).Value = dateTimePicker1.Value;

        openCon.Open();

        querySaveStaff.ExecuteNonQuery();
    }
}

【讨论】:

  • 为了获得最佳实践,字符串应为sqlCmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 50).Value = textBox1.Text.Trim();,其数据类型和精度与 SP 定义相匹配。
  • 由于某种原因,该字符串无法与我的 dateTimePicker 一起使用.. 另外,我是否将您为 querySaveStuff 放置的代码放在按钮单击中?
  • @DaleK 老实说,我不知道为什么这是有争议或令人困惑的。如果你想传递int - 传递int。如果你想传递nvarchar - 传递string。如果你想传递datetime - 传递DateTime。 :)
  • @mjwills 对此表示感谢 - 我刚刚进行了测试,因为我假设 new SqlParameter("@Test", SqlDbType.DateTime) { Value = "29 mar 2020" }; 会在分配了 Value 时执行转换,但我可以看到情况并非如此,尽管将参数声明为 DateType,但它仍然是传递给数据库的字符串。那不是我期望 TBH 的行为。感谢您澄清这一点。
【解决方案2】:

我看到您将值传递给您的过程而没有提及它们的类型,最好显示每个参数类型远离将来的许多其他问题。

首先检查您的 SQL 表列类型是否设置为 DATETIME。如果是这样,您需要检查您的 C# 字符串格式。 SQL 使用“yyyy-MM-dd HH:mm:ss.fff”日期格式。如果您使用以下值传递您的字符串:“2020-04-06 9:24:15.144”,它将通过而没有任何错误。但是你必须向 ADO.NET 表明你正在传递一个 DATETIME。

如果您不想处理字符串,则必须使用您的字符串格式将其解析为DateTime,然后将其传递给您的过程。

例子:

DateTime.ParseExact("YOUR DATE STRING", "YOUR DATET STRING FORMAT", System.Globalization.DateTimeFormatInfo.InvariantInfo);

但是,如果您不想将字符串解析为DateTime,请使用它(这适用于字符串和日期时间类型)。

示例如下:

static async Task Main(string[] args)
{
    string csharpDate = "2020-06-04 09:37:15.144";
    using (SqlConnection connection = new SqlConnection("YOUR CONNECTION STRING"))
    {
        using (SqlCommand command = new SqlCommand("YOUR PROCEDURE NAME", connection))
        {
            command.CommandType = CommandType.StoredProcedure;
            command.Parameters.Add("@DateParameter", SqlDbType.DateTime).Value = csharpDate;
            await connection.OpenAsync();
            await command.ExecuteNonQueryAsync();
        }
    }
}

【讨论】:

  • 传递日期,而不是字符串。 不要使用这个答案。
猜你喜欢
  • 2017-06-11
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 2017-05-06
  • 1970-01-01
相关资源
最近更新 更多