简体   繁体   English

从字符串转换日期时间时转换失败

[英]Conversion failed when converting datetime from character string

I am developing a C# VS 2008 / SQL Server 2005 Express website application.我正在开发 C# VS 2008 / SQL Server 2005 Express 网站应用程序。 I have tried some of the fixes for this problem but my call stack differs from others.我已经尝试了一些解决此问题的方法,但我的调用堆栈与其他方法不同。 And these fixes did not fix my problem.而这些修复并没有解决我的问题。 What steps can I take to troubleshoot this?我可以采取哪些步骤来解决此问题?

Here is my error:这是我的错误:

System.Data.SqlClient.SqlException was caught
  Message="Conversion failed when converting datetime from character string."
  Source=".Net SqlClient Data Provider"
  ErrorCode=-2146232060

  LineNumber=10
  Number=241
  Procedure="AppendDataCT"
  Server="\\\\.\\pipe\\772EF469-84F1-43\\tsql\\query"
  State=1
  StackTrace:
       at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
       at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
       at System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
       at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
       at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
       at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
       at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe)
       at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
       at ADONET_namespace.ADONET_methods.AppendDataCT(DataTable dt, Dictionary`2 dic) in c:\Documents and Settings\Admin\My Documents\Visual Studio 2008\WebSites\Jerry\App_Code\ADONET methods.cs:line 102

And here is the related code.这是相关的代码。 When I debugged this code, "dic" only looped through the 3 column names, but did not look into row values which are stored in "dt", the Data Table.当我调试这段代码时,“dic”只循环遍历 3 个列名,但没有查看存储在“dt”(数据表)中的行值。

public static string AppendDataCT(DataTable dt, Dictionary<string, string> dic)
{
    if (dic.Count != 3)
        throw new ArgumentOutOfRangeException("dic can only have 3 parameters");

    string connString = ConfigurationManager.ConnectionStrings["AW3_string"].ConnectionString;
    string errorMsg;

    try
    {               
        using (SqlConnection conn2 = new SqlConnection(connString))
        {
            using (SqlCommand cmd = conn2.CreateCommand())
            {
                cmd.CommandText = "dbo.AppendDataCT";
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Connection = conn2;
                foreach (string s in dic.Keys)
                {
                    SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);
                    p.SqlDbType = SqlDbType.VarChar;
                }

                conn2.Open();
                cmd.ExecuteNonQuery();
                conn2.Close();
                errorMsg = "The Person.ContactType table was successfully updated!";
            }
        }
    }

Here is my SQL stored proc:这是我的 SQL 存储过程:

ALTER PROCEDURE [dbo].[AppendDataCT] 
@col1 VARCHAR(50), 
@col2 VARCHAR(50),
@col3 VARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @TEMP DATETIME
SET @TEMP = (SELECT CONVERT (DATETIME, @col3))

INSERT INTO Person.ContactType (Name, ModifiedDate)
VALUES( @col2, @TEMP)
END

The input file has 3 columns.输入文件有 3 列。 The first two are varchars, but the 3rd one is also varchar I think, but it's represented as "3/11/2010".前两个是 varchars,但我认为第三个也是 varchar,但它表示为“3/11/2010”。 In this input file, a sample row looks like: "Benjamin|breakfast|3/11/2010".在此输入文件中,示例行类似于:“Benjamin|breakfast|3/11/2010”。 And I am trying to convert this date field from a string to a datetime here in my SP.我试图在我的 SP 中将此日期字段从字符串转换为日期时间。 Am I going about it the wrong way?我是不是用错了方法?

DataRow: col1|col2|col3 11|A2|1/10/1978 12|b2|2/10/1978 13|c2|3/10/1978 14|d2|4/10/1978数据行: col1|col2|col3 11|A2|1/10/1978 12|b2|2/10/1978 13|c2|3/10/1978 14|d2|4/10/1978

I think Belousov Pavel is correct.我认为别洛乌索夫帕维尔是正确的。 Inside your foreach you assign each dictionary item as a parameter.在 foreach 中,您将每个字典项分配为参数。 Each of those parameters are defined as being VarChar.这些参数中的每一个都被定义为 VarChar。 With the information provided it is logical to assume the problem is in the stored procedure.根据所提供的信息,可以合理地假设问题出在存储过程中。

Can you either post the code of the stored procedure or try and recreate the error inside SQL Management Studio by executing the stored procedure there.您可以发布存储过程的代码,或者通过在那里执行存储过程来尝试在 SQL Management Studio 中重新创建错误。

UPDATE...更新...

After looking at your stored procedure the code looks correct.查看您的存储过程后,代码看起来是正确的。 I was able to generate the error message you are getting using the following sql code.我能够使用以下 sql 代码生成您收到的错误消息。

declare @col3 varchar(50)声明@col3 varchar(50)

set @col3 = '|3/11/2010'设置@col3 = '|3/11/2010'

declare @temp datetime声明@temp 日期时间

set @temp = (select convert(datetime,@col3))设置@temp =(选择转换(日期时间,@col3))

Note that the value of @col3 starts with a pipe character.请注意,@col3 的值以管道字符开头。 If you remove the pipe character it works correctly.如果删除管道字符,它可以正常工作。

I would look closer at the values in the dictionary you are getting you parameter values from.我会仔细查看您从中获取参数值的字典中的值。 There may be an issue with the way you parsed the data.您解析数据的方式可能存在问题。

UPDATE 2更新 2

The code below is not confirmed to work but I think I see what you are trying to do.下面的代码未确认有效,但我想我明白你在做什么。 I assume the DataTable you are passing in has data like this:我假设您传入的 DataTable 具有如下数据:

col1|col2|col3 11|A2|1/10/1978 12|b2|2/10/1978 13|c2|3/10/1978 14|d2|4/10/1978 col1|col2|col3 11|A2|1/10/1978 12|b2|2/10/1978 13|c2|3/10/1978 14|d2|4/10/1978

If this is the case we don't need the dictionary that was passed in originally.如果是这种情况,我们不需要最初传入的字典。 I can also assume that you want the stored procedure to be executed once for each row in the DataTable.我还可以假设您希望对 DataTable 中的每一行执行一次存储过程。 The below method is similar to what you where doing although it runs the stored procedure for each row.下面的方法类似于您在做什么,尽管它为每一行运行存储过程。

What I am not sure from you explanation is if the first row of the DataTable contains the names of the columns, if not no worries then.我不确定你的解释是数据表的第一行是否包含列的名称,如果不是那么不用担心。 Hope this makes sense, leave more comments if you have questions.希望这是有道理的,如果您有任何问题,请留下更多评论。

    public static string TestMethod(DataTable dt)
    {
        string connString = "";
        string errorMsg = string.Empty;

        try
        {
            //loop through each row of the datatable. Not sure if the column names is a row.
            foreach (DataRow row in dt.Rows)
            {
                using (SqlConnection conn2 = new SqlConnection(connString))
                {
                    using (SqlCommand cmd = conn2.CreateCommand())
                    {
                        cmd.CommandText = "dbo.AppendDataCT";
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Connection = conn2;

                        cmd.Parameters.Add(new SqlParameter() { ParameterName = "@col1", SqlDbType = SqlDbType.VarChar, Value = row[0] });
                        cmd.Parameters.Add(new SqlParameter() { ParameterName = "@col2", SqlDbType = SqlDbType.VarChar, Value = row[1] });
                        cmd.Parameters.Add(new SqlParameter() { ParameterName = "@col3", SqlDbType = SqlDbType.VarChar, Value = row[2] });

                        conn2.Open();
                        cmd.ExecuteNonQuery();
                        conn2.Close();
                    }
                }                
            }
            errorMsg = "The Person.ContactType table was successfully updated!";
        }
        catch
        {
        }

        return errorMsg;
    }

Well, if you do this:好吧,如果你这样做:

SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);
p.SqlDbType = SqlDbType.VarChar;

all your parameters will be of type VARCHAR.您的所有参数都将是 VARCHAR 类型。 This might sound smart at first - it's not.乍一看这听起来很聪明 - 事实并非如此。

If you pass dates as varchar, you start getting into the messy business of date/time string formats - unless you always use the ISO-8601 format YYYYMMDD which works on any SQL Server installation, and with any locale / language / date setting.如果您将日期作为 varchar 传递,您将开始陷入混乱的日期/时间字符串格式业务 - 除非您始终使用 ISO-8601 格式YYYYMMDD ,该格式适用于任何 SQL Server 安装,并且具有任何区域设置/语言/日期设置。 Anything else becomes a gamble.其他任何事情都变成了赌博。 Not the whole world uses the MM/DD/YYYY format as in the US, and depending on your SQL Server's language or date format settings, your date might not be recognized, or even misinterpreted.并非全世界都像美国那样使用 MM/DD/YYYY 格式,并且根据 SQL Server 的语言或日期格式设置,您的日期可能无法识别,甚至被误解。 Just don't do it - it's a mess.只是不要这样做 - 这是一团糟。

Plus, really - if you have a date/time in your C# code - I would strongly recommend you pass that as a SqlDbType.DateTime to your SQL Server stored proc.另外,真的 - 如果你的 C# 代码中日期/时间 - 我强烈建议你将它作为SqlDbType.DateTime传递给你的 SQL Server 存储过程。 You're just gonna save yourself endless hours of debugging and messy conversions and stuf.......你只是要为自己节省无数小时的调试和混乱的转换和东西.......

Problem is in stored procedure, I think.我认为问题出在存储过程中。 May be one of input parameters is DateTime, but you wrote VarChar to this parameter.可能输入参数之一是 DateTime,但您将 VarChar 写入此参数。

UPDATE :更新

As I can see you don't use DataTable dt in your method AppendDataCT .正如我所看到的,您没有在方法AppendDataCT使用DataTable dt

You wrote that dic contains values [0]:[col1, col1] [1]:[col2, col2] [2]:[col3, col3].您写道 dic 包含值 [0]:[col1, col1] [1]:[col2, col2] [2]:[col3, col3]。 But it's wrong values... your code is但这是错误的值......你的代码是

SqlParameter p = cmd.Parameters.AddWithValue(s, dic[s]);

Then you send to col3 value = col3, as I understand.然后你发送到 col3 value = col3,据我所知。

May be you wanted to write也许你想写

SqlParameter p = cmd.Parameters.AddWithValue(s, dt[s]);

or something like this...或类似的东西...

You need to loop through the rows of the DataTable to get the data - you're adding the values of dic (your column names for month, day, year??) as SqlParameters..... This is what I'm assuming because the question is pretty scattered....您需要遍历 DataTable 的行以获取数据 - 您正在添加 dic 的值(您的月、日、年的列名??)作为 SqlParameters ..... 这就是我的假设因为问题很分散....

Note: Not completely functioning code -注意:不完全运行的代码 -

foreach(DataRow dr in dt.Rows)
{
    DateTime date = new DateTime();

    foreach(string s in dic.Keys)
    {  
        switch(dic[s])
        {
            case "Month":
                date.Month = dr[dic[s]];
                break;
            case "Day":
                date.Day = dr[dic[s]];
                break;
            case "Year":
                date.Year = dr[dic[s]];
                break;
        }

    }

    // If valid date
    SqlParameter p = cmd.Parameters.AddWithValue("Date", date);
    p.SqlDbType = SqlDbType.DateTime;      


}

UPDATE: You will need to handle your own data validation - otherwise, here you go更新:您将需要处理您自己的数据验证 - 否则,您去吧

    using (SqlConnection conn2 = new SqlConnection(connString))
    {
        using (SqlCommand cmd = conn2.CreateCommand())
        {
            conn2.Open();               


            foreach(DataRow dr in dt.Rows)
            {
                 SqlParameter col1 = cmd.Parameters.AddWithValue(dic[0], dr[0].ToString());
                 SqlParameter col2 = cmd.Parameters.AddWithValue(dic[1], dr[1].ToString());
                 SqlParameter col3 = cmd.Parameters.AddWithValue(dic[2], Convert.ToDateTime(dr[2]));

                 cmd.ExecuteNonQuery();

            }

            conn2.Close();
        }
   }

In my case I had my INSERT query's values in the wrong order:在我的情况下,我的 INSERT 查询的值顺序错误:

INSERT INTO my_table(
     status       --varchar
    , created_on  --datetime2
) VALUES (
     @created_on  --datetime2
    , @status     --varchar
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从C#中的字符串转换日期时间时转换失败 - Conversion failed when converting datetime from character string in C# 从字符串转换日期和/或时间时,DateTime转换失败 - DateTime conversion failed when converting date and/or time from character string 从字符串转换日期时间时转换失败 - Conversion failed when converting datetime from character string 从字符串转换日期时间时转换失败 - Conversion failed when converting datetime from character string 从字符串转换日期时间时转换失败 - Conversion failed when converting datetime from character string 从字符串DateTime转换日期和/或时间时转换失败 - Conversion failed when converting date and/or time from character string DateTime 从asp.net mvc 5中的字符串转换日期时间时,转换失败 - conversion failed when converting datetime from character string in asp.net mvc 5 将C#datetime发送到SQL Server-错误“从字符串转换日期和/或时间时转换失败” - Send C# datetime to SQL Server - error “Conversion failed when converting date and/or time from character string” 从字符串转换日期时间时转换失败。 Linq To SQL和OpenXML - Conversion failed when converting datetime from character string. Linq To SQL & OpenXML 错误:从字符串.NET SQL Server转换日期时间时转换失败 - Error: Conversion failed when converting datetime from character string .NET SQL Server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM