即使没有 datetime 列,也获取“将 varchar 数据类型转换为 datetime 数据类型导致超出范围的值”

Posted

技术标签:

【中文标题】即使没有 datetime 列,也获取“将 varchar 数据类型转换为 datetime 数据类型导致超出范围的值”【英文标题】:Getting "the conversion of a varchar data type to a datetime data type resulted in an out-of-range value" even if there is no datetime column 【发布时间】:2020-05-26 13:01:45 【问题描述】:

我的 SQL Server 数据库中有一个过程,它返回记录集中的一些日期,我在其中获取日期的列的数据类型为 varchar。我正在使用 LINQ2SQL 来执行该过程。

问题是,当我在 SSMS 中执行该过程时,它可以完美执行而没有任何错误,但是当我通过我的应用程序执行它时,它给出了

导致将 varchar 数据类型转换为 datetime 数据类型 在一个超出范围的值

错误。我还检查了由 LINQ2SQL 类生成器为该过程的记录集生成的类也不包含任何数据类型为datetime 的属性。

过程太长,无法共享,但我正在共享 LINQ2SQL 类生成器检测到的过程的最终 SELECT 以生成类。就在这里

DECLARE @finalResultSetTempTable AS TABLE ( 
                                              cd_id               BIGINT NOT NULL , 
                                              service_id          INT NULL , 
                                              resident_id         VARCHAR(20) , 
                                              cd_Date             VARCHAR(20) , 
                                              cd_StartTime        VARCHAR(20) , 
                                              cd_EndTime          VARCHAR(20) , 
                                              Pre_travelTime      VARCHAR(20) , 
                                              Post_travelTime     VARCHAR(20) , 
                                              cd_TimeDuration     VARCHAR(20) , 
                                              UnitType            INT , 
                                              NoOfUnits           INT , 
                                              cd_IsCompleted      BIT , 
                                              AssignedTo          INT , 
                                              cd_status           VARCHAR(50) , 
                                              Service_name        VARCHAR(200) , 
                                              Application_Name    VARCHAR(50) , 
                                              emp_first_name      VARCHAR(200) , 
                                              emp_last_name       VARCHAR(200) , 
                                              resident_first_name VARCHAR(200) , 
                                              resident_last_name  VARCHAR(200) , 
                                              address             VARCHAR(200) , 
                                              suburb              VARCHAR(200) , 
                                              state               VARCHAR(200) , 
                                              postCode            VARCHAR(200)
                                              );

SELECT cd_id , service_id , resident_id , FORMAT(CAST(cd_Date AS DATETIME) , 'yyyy-MM-dd') AS cd_Date , ISNULL(cd_StartTime , '12:00 AM') AS cd_StartTime , ISNULL(cd_EndTime , '12:00 AM') AS cd_EndTime , Pre_travelTime , Post_travelTime , ISNULL(cd_TimeDuration , '0') AS cd_TimeDuration , UnitType , NoOfUnits , cd_IsCompleted , AssignedTo , cd_status , Service_name , emp_first_name , emp_last_name , resident_first_name , resident_last_name , address , suburb , state , postCode , Application_Name
            FROM @finalResultSetTempTable

LINQ2SQL生成的类如下

public partial class sp_GetServicesForBulkUpdateResult


    private long _cd_id;

    private System.Nullable<int> _service_id;

    private string _resident_id;

    private string _cd_Date;

    private string _cd_StartTime;

    private string _cd_EndTime;

    private string _Pre_travelTime;

    private string _Post_travelTime;

    private string _cd_TimeDuration;

    private System.Nullable<int> _UnitType;

    private System.Nullable<int> _NoOfUnits;

    private System.Nullable<bool> _cd_IsCompleted;

    private System.Nullable<int> _AssignedTo;

    private string _cd_status;

    private string _Service_name;

    private string _emp_first_name;

    private string _emp_last_name;

    private string _resident_first_name;

    private string _resident_last_name;

    private string _address;

    private string _suburb;

    private string _state;

    private string _postCode;

    private string _Application_Name;

    public sp_GetServicesForBulkUpdateResult()
    
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_id", DbType="BigInt NOT NULL")]
    public long cd_id
    
        get
        
            return this._cd_id;
        
        set
        
            if ((this._cd_id != value))
            
                this._cd_id = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_service_id", DbType="Int")]
    public System.Nullable<int> service_id
    
        get
        
            return this._service_id;
        
        set
        
            if ((this._service_id != value))
            
                this._service_id = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_resident_id", DbType="VarChar(20)")]
    public string resident_id
    
        get
        
            return this._resident_id;
        
        set
        
            if ((this._resident_id != value))
            
                this._resident_id = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_Date", DbType="NVarChar(4000)")]
    public string cd_Date
    
        get
        
            return this._cd_Date;
        
        set
        
            if ((this._cd_Date != value))
            
                this._cd_Date = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_StartTime", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
    public string cd_StartTime
    
        get
        
            return this._cd_StartTime;
        
        set
        
            if ((this._cd_StartTime != value))
            
                this._cd_StartTime = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_EndTime", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
    public string cd_EndTime
    
        get
        
            return this._cd_EndTime;
        
        set
        
            if ((this._cd_EndTime != value))
            
                this._cd_EndTime = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Pre_travelTime", DbType="VarChar(20)")]
    public string Pre_travelTime
    
        get
        
            return this._Pre_travelTime;
        
        set
        
            if ((this._Pre_travelTime != value))
            
                this._Pre_travelTime = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Post_travelTime", DbType="VarChar(20)")]
    public string Post_travelTime
    
        get
        
            return this._Post_travelTime;
        
        set
        
            if ((this._Post_travelTime != value))
            
                this._Post_travelTime = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_TimeDuration", DbType="VarChar(20) NOT NULL", CanBeNull=false)]
    public string cd_TimeDuration
    
        get
        
            return this._cd_TimeDuration;
        
        set
        
            if ((this._cd_TimeDuration != value))
            
                this._cd_TimeDuration = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UnitType", DbType="Int")]
    public System.Nullable<int> UnitType
    
        get
        
            return this._UnitType;
        
        set
        
            if ((this._UnitType != value))
            
                this._UnitType = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_NoOfUnits", DbType="Int")]
    public System.Nullable<int> NoOfUnits
    
        get
        
            return this._NoOfUnits;
        
        set
        
            if ((this._NoOfUnits != value))
            
                this._NoOfUnits = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_IsCompleted", DbType="Bit")]
    public System.Nullable<bool> cd_IsCompleted
    
        get
        
            return this._cd_IsCompleted;
        
        set
        
            if ((this._cd_IsCompleted != value))
            
                this._cd_IsCompleted = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_AssignedTo", DbType="Int")]
    public System.Nullable<int> AssignedTo
    
        get
        
            return this._AssignedTo;
        
        set
        
            if ((this._AssignedTo != value))
            
                this._AssignedTo = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_cd_status", DbType="VarChar(50)")]
    public string cd_status
    
        get
        
            return this._cd_status;
        
        set
        
            if ((this._cd_status != value))
            
                this._cd_status = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Service_name", DbType="VarChar(200)")]
    public string Service_name
    
        get
        
            return this._Service_name;
        
        set
        
            if ((this._Service_name != value))
            
                this._Service_name = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_emp_first_name", DbType="VarChar(200)")]
    public string emp_first_name
    
        get
        
            return this._emp_first_name;
        
        set
        
            if ((this._emp_first_name != value))
            
                this._emp_first_name = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_emp_last_name", DbType="VarChar(200)")]
    public string emp_last_name
    
        get
        
            return this._emp_last_name;
        
        set
        
            if ((this._emp_last_name != value))
            
                this._emp_last_name = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_resident_first_name", DbType="VarChar(200)")]
    public string resident_first_name
    
        get
        
            return this._resident_first_name;
        
        set
        
            if ((this._resident_first_name != value))
            
                this._resident_first_name = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_resident_last_name", DbType="VarChar(200)")]
    public string resident_last_name
    
        get
        
            return this._resident_last_name;
        
        set
        
            if ((this._resident_last_name != value))
            
                this._resident_last_name = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_address", DbType="VarChar(200)")]
    public string address
    
        get
        
            return this._address;
        
        set
        
            if ((this._address != value))
            
                this._address = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_suburb", DbType="VarChar(200)")]
    public string suburb
    
        get
        
            return this._suburb;
        
        set
        
            if ((this._suburb != value))
            
                this._suburb = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_state", DbType="VarChar(200)")]
    public string state
    
        get
        
            return this._state;
        
        set
        
            if ((this._state != value))
            
                this._state = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_postCode", DbType="VarChar(200)")]
    public string postCode
    
        get
        
            return this._postCode;
        
        set
        
            if ((this._postCode != value))
            
                this._postCode = value;
            
        
    

    [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Application_Name", DbType="VarChar(50)")]
    public string Application_Name
    
        get
        
            return this._Application_Name;
        
        set
        
            if ((this._Application_Name != value))
            
                this._Application_Name = value;
            
        
    

我编写的执行该过程的代码如下

Service service;
                res = new List<Service>();
                var resultSet = context.sp_GetServicesForBulkUpdate(assignedTo, _fromDate, _toDate, programName, serviceID.ToString(), "ALL");

                foreach (var item in resultSet)
                
                    service = new Service();
                    service.serviceDeliveryID = item.cd_id.ToString();
                    service.serviceID = item.service_id.ToString();
                    service.serviceStatus = item.cd_status;
                    service.serviceName = item.Service_name;
                    service.serviceStartDate = string.IsNullOrEmpty(item.cd_Date) ? "" : item.cd_Date;
                    service.serviceStartTime = item.cd_StartTime;
                    service.serviceEndDate = string.IsNullOrEmpty(item.cd_Date) ? "" : item.cd_Date;
                    service.serviceEndTime = item.cd_EndTime;
                    service.serviceLocation = ((string.IsNullOrEmpty(item.address) ? "" : item.address + ", ") + (string.IsNullOrEmpty(item.suburb) ? "" : item.suburb + ", ") + (string.IsNullOrEmpty(item.state) ? "" : item.state + ", ") + (string.IsNullOrEmpty(item.postCode) ? "" : item.postCode + " ")).Trim().TrimEnd(',');

                    service.serviceUnitType = item.UnitType;
                    service.serviceNoOfUnits = item.NoOfUnits;

                    service.employeeID = Int32.Parse((item.AssignedTo.HasValue ? item.AssignedTo.ToString() : "0"));
                    service.employeeFirstName = string.IsNullOrEmpty(item.emp_first_name) ? "" : item.emp_first_name;
                    service.employeeLastName = string.IsNullOrEmpty(item.emp_last_name) ? "" : item.emp_last_name;

                    service.residentID = item.resident_id;
                    service.residentFirstName = item.resident_first_name;
                    service.residentLastName = item.resident_last_name;

                    service.isAssigned = (item.AssignedTo.HasValue && item.AssignedTo != 0) ? true : false;

                    service.isActive = item.cd_IsCompleted.ToString() == "0" ? false : true;
                    service.serviceAppName = item.Application_Name;


                    res.Add(service);
                

如果可能有任何帮助,这里是过程返回的一些示例数据

任何人都可以提供任何帮助吗?

编辑

附件截图中的日期格式是m/dd/yyyy,因为是excel表格。实际格式为yyyy-mm-dd

【问题讨论】:

可能是因为SELECT语句中的FORMAT(CAST(cd_Date AS DATETIME) , 'yyyy-MM-dd') AS cd_Date。 我在其他程序中也使用了相同的方法,运行顺利。我只收到此过程中的错误。 @SurajKumar 你是对的,FORMAT(CAST(cd_Date AS DATETIME) , 'yyyy-MM-dd') 造成了问题。谢谢大佬。 【参考方案1】:

在调查过程后,我发现FORMAT(CAST(cd_Date AS DATETIME) , 'yyyy-MM-dd') AS cd_Date 造成了问题。因为我的数据已经是那种格式,当CAST(cd_Date AS DATETIME) 尝试转换datetime 中的varchar 值时,它会给出错误。

据我说,CAST(cd_Date AS DATETIME) 期待varchar 日期为yyyy-dd-MM 格式,因为我用来查询数据库的用户的语言设置为英国(我从this question 得到这个提示),所以当它将日期转换为2015-05-16(格式为yyyy-MM-dd),它会给出错误

将 varchar 数据类型转换为 datetime 数据类型导致值超出范围

如果我有错误,请纠正我,如果有遗漏,请添加任何内容。

【讨论】:

【参考方案2】:
DECLARE @finalResultSetTempTable AS TABLE ( 
                                              cd_id               BIGINT NOT NULL , 
                                              service_id          INT NULL , 
                                              resident_id         VARCHAR(20) , 
                                              cd_Date             VARCHAR(20) , 
                                              cd_StartTime        VARCHAR(20) , 
                                              cd_EndTime          VARCHAR(20) , 
                                              Pre_travelTime      VARCHAR(20) , 
                                              Post_travelTime     VARCHAR(20) , 
                                              cd_TimeDuration     VARCHAR(20) , 
                                              UnitType            INT , 
                                              NoOfUnits           INT , 
                                              cd_IsCompleted      BIT , 
                                              AssignedTo          INT , 
                                              cd_status           VARCHAR(50) , 
                                              Service_name        VARCHAR(200) , 
                                              Application_Name    VARCHAR(50) , 
                                              emp_first_name      VARCHAR(200) , 
                                              emp_last_name       VARCHAR(200) , 
                                              resident_first_name VARCHAR(200) , 
                                              resident_last_name  VARCHAR(200) , 
                                              address             VARCHAR(200) , 
                                              suburb              VARCHAR(200) , 
                                              state               VARCHAR(200) , 
                                              postCode            VARCHAR(200)
                                              );

SELECT cd_id , service_id , resident_id ,  CONVERT(datetime,cd_Date,103) AS cd_Date , ISNULL(cd_StartTime , '12:00 AM') AS cd_StartTime , ISNULL(cd_EndTime , '12:00 AM') AS cd_EndTime , Pre_travelTime , Post_travelTime , ISNULL(cd_TimeDuration , '0') AS cd_TimeDuration , UnitType , NoOfUnits , cd_IsCompleted , AssignedTo , cd_status , Service_name , emp_first_name , emp_last_name , resident_first_name , resident_last_name , address , suburb , state , postCode , Application_Name
            FROM @finalResultSetTempTable

【讨论】:

您是否检查了相关数据集中日期列中的任何问题? 是的@Harshana 我发现了问题并解决了它。我还发布了解决方案作为答案。

以上是关于即使没有 datetime 列,也获取“将 varchar 数据类型转换为 datetime 数据类型导致超出范围的值”的主要内容,如果未能解决你的问题,请参考以下文章

在mysql datetime上触发java函数

默认日期时间值显示在日期时间列中随机记录的数据表中,即使我没有在任何地方分配值

即使在创建之后,表中也没有列

有没有办法确保 SQL Server 标识列值即使在多次服务器重新启动后也始终保持一致?

pandas使用to_datetime函数将字符串时间数据列转化为时间对象数据列通过DatetimeProperties对象获取日期对象的年份信息(year)

pandas使用to_datetime函数将字符串时间数据列转化为时间对象数据列通过DatetimeProperties对象获取日期对象的当月第几天信息(day)