System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow - c#

I am working with C#.net and also SQL Server 2008.
I have the following error, when trying to run a test unit within my project.
System.Data.SqlTypes.SqlTypeException:
SqlDateTime overflow. Must be between
1/1/1753 12:00:00 AM and 12/31/9999
11:59:59 PM..
Database Table
Column Name: createddate
Type: datetime
Default Value: (getdate())
Allow Nulls: No.
I don't want to insert the createddate as part of my INSERT query.
When I manually enter some data into the database table I get the following error:
The row was successfully committed
to the database. However, a problem
occurred when attempting to retrieve
the data back after commit. Because
of this the displayed data within the
row is read-only. To fix this
problem, please re-run the query.
I don’t understand why I am getting this error and cannot find anyone who has had this problem. Can anyone help?

Matt is most likely on the right track. You have defined a default value for your column - however, that will only take effect if you actually insert something in your table in the database.
When you do a unit test, as you say, you most likely initialize the DateTime variable to something (or not - then it'll be DateTime.MinValue, which is 01/01/0001) and then you send that to the SQL Server and this value is outside the valid range for a DATETIME on SQL Server (as the error clearly states).
So what you need to do is add a line to your .NET unit test to initialize the DateTime variable to "DateTime.Today":
DateTime myDateTime = DateTime.Today
and then insert that into SQL Server.
OR: you can change your SQL INSERT statement so that it does not insert a value for that column - it looks like right now, it does do that (and attempts to insert that - for SQL Server - invalid date into the table). If you don't specify that column in your INSERT, then the column default of getdate() will kick in and insert today's date into the column.
Marc

Are you using Linq to SQL to write your unit test?
If you are, it might be bypassing the getdate() default value, and using some other value instead which falls outside the valid range.

I got the same issue, I was using Linq with the DataClasses files automatically generated by VS2010.
The I realised that Linq is not using the default value (GetDate()) but it will send a Datetime.Min value. As the consequence the SQL server will reject this datetime "01/01/0001" because it's not in range.
What I did to fix it is to always set the value to Datetime.Now or Datetime.Today and so Linq will not send the bad Min Datetime value anymore.

You are probably getting an overflow error in your unit test because you are passing in an uninitialised DateTime with the value DateTime.MinValue which is outside the allowable range for SQL's datetime.
I think I have seen that error message when modifying the table manually, it isn't a problem, just refresh the table.

are you using a data context class setup with the DBML file and all that jazz? If so, then you can click on the field in your DBML file and set the "Auto Generated Value property" to True. Visual Studio must already know to do this with the Pkey fields, but has to be set for these "timestamping" sort of actions

Related

DateTime.MaxValue saves as Zero in mysql

I am using C# and MySql. I have a requirement where I need to save DateTime.MaxValue to one of the column.
ADO.NET code gives me below value for DateTime.MaxValue
12/31/9999 11:59:59 PM
When I save this in mysql, I see that the value for that datetime(3) column is saved as:
0000-00-00 00:00:00.000
Sample ADO.NET Code
DateTime time = DateTime.MaxValue;
sqlCommand.Parameters.AddWithValue("Expires", time);
sqlCommand.ExecuteNonQuery();
DataType of the column is datetime(3)
I still cannot figure it out why DateTime.MaxValue is saved as 0000-00-00 00:00:00.000
Any thoughts around this?
A DATETIME column can store values up to '9999-12-31 23:59:59'. DateTime.MaxValue is actually 9999-12-31 23:59:59.9999999. When you try to insert it, the fractional seconds overflow the maximum size of the field.
Normally (in STRICT mode), MySQL Server would issue a datetime field overflow error. But if you're running your server in ANSI mode, the overflow is silently converted to the "invalid" date time value 0000-00-00.
One way to fix this problem is to use STRICT mode in your MySQL Server.
Another way is to specify the column type as DATETIME(6), which allows the fractional seconds to be stored.
A third way is to truncate the fractional seconds from your DateTime objects in C# before inserting them in the database.
Maybe some trigger prevents from saving such a high date to your column?
Have u tried inserting that date from SQL query ?
I did some tests in Oracle DB, and all went smoothly.
It shouldnt be different in mysql ...

Entity Framework not claiming datetime.now is null

Here is my code:
UVCUpdate update = new UVCUpdate();
update.CurrentDate = DateTime.Now;
_context.UVCUpdates.Add(update);
_context.SaveChanges();
Now I am getting an inner exception though saying this:
Cannot insert the value NULL into column 'CurrentDate', table 'bLinked.dbo.BlackbookUpdateUVC'; column does not allow nulls. INSERT fails.
If I output the DateTime.Now just before this code it outputs:
9/15/2016 7:26:35 PM
My data type for CurrentDate in the db is set to datetime and in the class it is set to DateTime. Neither allow for nulls, but DateTime.Now should not be null right?
It almost always happens when there is mismatch between so called "store generated pattern" between EF model and database. If model column has store generated pattern of Identity or Computed - that means EF will be sure those values will be automatically provided by database on insert or update, and there is no need to include them in INSERT or UPDATE statements. Missing values will have default NULL value, and if this column is non-nullable in database at the same time, and is not really computed or identity - you have the error in question.
I am sorry guys, I feel like an idiot. Thank you to Leopard.
I went to get the UVCUpdate class to show him and realized that when I copied that class from another class I accidentally left [DatabaseGenerated(DatabaseGeneratedOption.Identity)] in the class for the CurrentDate. So it was likely attempting to send a null value to the SQL so the SQL would create an ID, but the field was set to not allow nulls. CurrentDate was not supposed to be an ID so I removed that and now it works...

How can I make SQL Server 2012 truncate insertions if they are too big?

So I have a table with a column of type VARCHAR (100) and I'm wondering if there's a way to configure SQL Server 2012 (T-SQL) so that if a transaction tries to submit a string of 101+ characters then it takes the first 100.
Is this possible, or should I be doing the truncation in the C# side of things ???
Normally, SQL Server will present an error on any attempt to insert more data into a field than it can hold
String or binary data would be truncated. The statement has been terminated.
SQL Server will not permit a silent truncation of data just because the column is too small to accept the data. But there are other ways that SQL Server can truncate data that is about to be inserted into a table that will not generate any form of error or warning.
By default, ANSI_WARNINGS are turned on, and certain activities such as creating indexes on computed columns or indexed views require that they be turned on. But if they are turned off, SQL Server will truncate the data as needed to make it fit into the column. The ANSI_WARNINGS setting for a session can be controlled by
SET ANSI_WARNINGS { ON|OFF }
Unlike with an insert into a table, SQL Server will quietly cut off data that is being assigned to a variable, regardless of the status of ANSI_WARNINGS. For instance:
declare #smallString varchar(5)
declare #testint int
set #smallString = 'This is a long string'
set #testint = 123.456
print #smallString
print #testint
Results is:
This
123
This can occasionally show itself in subtle ways since passing a value into a stored procedure or function assigns it to the parameter variables and will quietly do a conversion. One method that can help guard against this situation is to give any parameter that will be directly inserted into a table a larger datatype than the target column so that SQL Server will raise the error, or perhaps to then check the length of the parameter and have custom code to handle it when it is too long.
For instance, if a stored procedure will use a parameter to insert data into a table with a column that is varchar(10), make the parameter varchar(15). Then if the data that is passed in is too long for the column, it will rollback and raise a truncation error instead of silently truncating and inserting. Of course, that runs the risk of being misleading to anyone who looks at the stored procedures header information without understanding what was done.
Source: Silent Truncation of SQL Server Data Inserts
Do this on code level. When you are inserting the current field check field length and Substring it.
string a = "string with more than 100 symbols";
if(a.Length > 100)
a = a.Substring(0, 100);
After that you are adding a as sql parameter to the insert query.
The other way is to do it in the query, but again I don't advice you to do that.
INSERT INTO Table1('YourColumn') VALUES(LEFT(RTRIM(stringMoreThan100symbols), 100))
LEFT is cutting the string and RTRIM is performing Trim operation of the string.
My suggestion would be to make the application side responsible for validating the input before calling any DB operation.
SQL Server silently truncates any varchars you specify as stored procedure parameters to the length of the varchar. So you should try considering stored procedures for you requirements. So it will get handled automatically.
If you have entity classes (not necessarily from EF) you can use StringLength(your field length) attribute to do this.

Error While Comparing Dates

I have an NVARCHAR column named Receivingdate. I want to compare its content with the current time, but when I call WHERE (Receivingdate < Getdate()), I get the following error:
The conversion of nvarchar to datetime resulted in an out of range value
I insert the data using the following call from C#:
DateTime.Now.AddDays(ces).ToString("dd/MM/yyyy");
I'm wondering what I'm doing wrong.
What you're doing wrong is storing dates in an NVARCHAR column. Please stop doing that. Fix your table and make that column using the DATE data type. The error is caused by garbage data getting into your table. Find those rows using:
SELECT Receivingdate FROM dbo.YourTable
WHERE ISDATE(ReceivingDate) = 0;
Now, you'll need to either correct or get rid of those before you fix the data type. Then:
ALTER TABLE dbo.YourTable
ALTER COLUMN ReceivingDate DATE;
Next, stop converting to a regional string format when inserting. Just insert the DateTime value from C# without calling .ToString() at all. There is absolutely no reason you should ever be converting to date to string and back again through any of this process, except at the point where you want to display it.
Your error is that you are trying to compare a string to a date. Dates are numbers. The only time to worry about format is when you are displaying them.
For what you have shown so far, change your c# code from
DateTime.Now.AddDays(ces).ToString("dd/MM/yyyy");
to
DateTime.Today;
and you should be ok.

How do you get a NOW() value in C# using the MySQL Connector?

Is it possible in an easy way to get the NOW() timestamp from an UPDATE query? I'm trying to save the "lastupdated" value in the local cache, or is there in any way possible to get the exact MySQL server time which the update query was executed?
Best Regards; Görgen
To my knowledge, MySQL doesn't have functionality like Oracle's RETURNING or SQL Server's OUTPUT clause to be able to save a query by returning values from INSERT/UPDATE statements. So that means two statements minimum...
is there in any way possible to get the exact MySQL server time which the update query was executed?
The best I can think of is to define an audit column (they were standard approach at my previous work) for logging the timestamp when the record was updated. In MySQL, you can default the value so on update it is set to the timestamp value at that time:
ALTER TABLE your_table
ADD COLUMN update_timestamp TIMESTAMP NOT NULL DEFAULT ON UPDATE CURRENT_TIMESTAMP
...then this gives you a specific column value to query.
The usual way is to set a LastUpdated field in the database, either in the stored procedure or in a trigger. Then you can read it back.

Categories