I'm trying to find a way to correctly format a Date in a SELECT statement that loads data from an old Visual Fox Pro Database. I need to do this so that I can load it into a CSV, then load it into MySQL, which takes the date format 'yyyy-MM-dd'.
This is my query at the moment;
var dbfCmd = new OleDbCommand(#"SELECT ct_id, ct_cmpid, ct_empid, ct_pplid, ct_cntid, ct_pplnm, ct_date, ct_time, ct_type, ct_doneby, ct_desc FROM contacts", dbfCon);
I need to find a way to format the ct_date column. I've tried a number of ways so far, including using FDATE and FORMAT, but nothing has worked so far. I've looked through the supported commands for OleDB but still haven't come across anything.
Can anyone inform me of the correct way to format the Date query so that I can import to MySQL?
Do not format the date on the server.
Receive as a date column, then read as a DateTime value when enumerating the query. Finally format it on your client in the specify way when writing the file.
Although it has been suggested to convert the data in C# to date format, if you REALLY want to pull the date formatted from VFP OleDb query, you could do this for your date column
STUFF( STUFF( DTOS( ct_date ), 5, 0, "-"), 8, 0, "-" )
The VFP Function DTOS will convert a date (or datetime) to a string and will always be in the format of YYYYMMDD. The STUFF command will do the inserting of the hyphen character to properly set to YYYY-MM-DD for you.
You could simply use ToString("yyyy-MM-dd") but better do not even do that. You could directly connect to MySQL and insert data into it using VFP commands and call that via an ExecScript. Or you could directly import from VFP within MySQL connection (I don't use MySQL but you can do that with other databases like MS SQL Server, postgreSQL etc so I assume MySQL is also capable doing that).
Yet another alternative would be to use an XML format to import/export which is much more reliable than plain text.
Yet another way, you could connect to MySQL and VFP, fill MySQL DataTable with your data and submit changes.
IOW using a text file in between would be my last suggestion.
PS: Have a look at FileHelpers.
Related
I have a program that is moving data between two tables in a database. For this, I am using a SQL query and the System.Data.SqlClient package.
All of a sudden, this query throws an error when executing.
SQLCommand.ExecuteNonQuery is throwing:
Conversion failed when converting date and/or time from character string.
I have isolated the line with the conversion to:
AND DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14
where a.date is the datetime as varchar. The query is a INSERT-SELECT query, and if I run only the SELECT part, it works. Even more strange is that this query works perfectly fine to run in SSMS both with and without data found.
Have anyone else seen this case lately?
where a.date is the datetime as varchar.
well there's your main problem. If you are storing a date/time: use the appropriate storage type in the database. You have a wide range to choose from, for example date, smalldatetime, datetime and datetime2 - and: SQL Server will know how to correctly understand and work with that data.
Ultimately the problem here is that SUBSTRING(a.date, 1, 10) isn't giving a result that SQL Server understands as a date through implicit string conversion operations. This approach is a: inefficient, and b: brittle (especially between cultures), hence why you simply shouldn't do that. If you store the data appropriately: all the problems will go away.
However! You could also use CONVERT to tell SQL Server to interpret the string as a date/time, explicitly telling it the format you expect (as a number code), so that it stands a chance.
If your a.date (and substring) isn't in one of the supported formats: abandon all hope.
BTW; DATEDIFF(dd,GETDATE(),SUBSTRING(a.date, 1, 10))<14 is probably more efficiently done by way of calculating the start-date/end-date of your range once and just comparing with a comparison operator. GETDATE() won't change per row, so "14 days from now" won't change per row. This would make your query a lot more efficient, especially when combined with the correct date/time format - it becomes:
a.date <= #end -- or < #end, or > #end, or >= #end
which can use an index.
Interesting! "No changes has been made to the code, and no new data has entered the queried table since then."
So the question why it doesn't work as the same way really have a many choice for you
Your code just don't run into the problem date data before.
Application server have something changed like date region/culture so it affect the application way of seeing date when communicate with DB server
the 2. but from DB server e.g. Infra team upgrade/patch the DB server, the configuration is affect so this has problem with date format , update/patching Db cause the build-in functions too have upgraded behavior too!)
The statement in double-quote is false.
System.Data.SqlClient 's feature when process the query ?
and so on...
I think finding the causes just from this little information is the very difficult task.
From my little search ,you really should go diving into the query and data as the others tried to suggest.
Conversion failed when converting date and/or time from character string while inserting datetime
This question already has answers here:
Insert, select and update DateTime
(2 answers)
Closed 8 years ago.
I have a table with a Date type. And I want to insert the date in this format: dd-mm-yyyy (ex: 27/10/2014). I already tried with String but the problem is when i want do a search with 2 Dates the SQL just compare the days. I just realy need the day, month and year. And in C# i use DateTime.Now.ToShortDateString(); to retrieve the date and insert in the database.
I used that query to search the dates:
Query:
SELECT *
FROM [TABLE]
WHERE ([COLUMN] >= '25/10/2014' AND [COLUMN] <= '26/10/2014');
Its any way to save the data like the format i want? Then will be more easy to select the data I want.
Sorry for my english, please help thanks.
SQL Server doesn't store a DateTime in any string format - it's stored as an 8 byte numerical value.
The various settings (language, date format) only influence how the DateTime is shown to you in SQL Server Management Studio - or how it is parsed when you attempt to convert a string to a DateTime.
There are many formats supported by SQL Server - see the MSDN Books Online on CAST and CONVERT. Most of those formats are dependent on what settings you have - therefore, these settings might work some times - and sometimes not.
The way to solve this is to use the (slightly adapted) ISO-8601 date format that is supported by SQL Server - this format works always - regardless of your SQL Server language and dateformat settings.
The ISO-8601 format is supported by SQL Server comes in two flavors:
YYYYMMDD for just dates (no time portion); note here: no dashes!, that's very important! YYYY-MM-DD is NOT independent of the dateformat settings in your SQL Server and will NOT work in all situations!
or:
YYYY-MM-DDTHH:MM:SS for dates and times - note here: this format has dashes (but they can be omitted), and a fixed T as delimiter between the date and time portion of your DATETIME.
This is valid for SQL Server 2000 and newer.
If you use SQL Server 2008 or newer and the DATE datatype (only DATE - not DATETIME!), then you can indeed also use the YYYY-MM-DD format and that will work, too, with any settings in your SQL Server.
Don't ask me why this whole topic is so tricky and somewhat confusing - that's just the way it is. But with the YYYYMMDD format, you should be fine for any version of SQL Server and for any language and dateformat setting in your SQL Server.
The recommendation for SQL Server 2008 and newer is to use DATE if you only need the date portion, and DATETIME2(n) when you need both date and time. You should try to start phasing out the DATETIME datatype if ever possible
So in your concrete case, I would rewrite that query as:
SELECT *
FROM [TABLE]
WHERE ([COLUMN] >= '20141025' AND [COLUMN] <= '20141026');
to be independent of any language, regional or dateformat settings in SQL Server ....
Never ever save your date and datetime values as strings. And always parameterize your SQL. If you want to make it easy for yourself, use a micro-ORM like Dapper to simplify such operations:
var result = connection.Query(
"SELECT * FROM EXAMPLE where data between #lower and #upper",
new { lower = DateTime.Parse("10/25/14"), upper = DateTime.Parse("10/26/14") });
I also recommend you use concrete data types o return information from the database, so you will not be forced to use dynamic properties.
Yes, for example in MS SQL, you can save the data in datetime2 (or equivalent) and format it on the way out. This approach will allow you to compare the dates.
Steps you can take:
change the Data type for the column at hand from string to datatime
You can apply formatting on the date upon retrieving. For example, users from Europe will have different date structure from users in north America.
so i have a string "09/15/2014" and in c# it converts it to date:
DateTime from = Convert.ToDateTime(fromdate);
this outputs "9/15/2014" and when I send it over to sql I get this:
select convert(varchar, '9/1/2014 12:00:00 AM', 101)
which doesn't work for me because I need to keep any leading zero's.
help?
If you're worried about the string formats for dates with Sql Server, you're doing it wrong. As a comment to another answer indicates, SQL Server internally stores all dates in a machine-optimized numeric format that is not easily human-readable. It only converts them to a human-understandable format for output in your developer tools.
When sending dates to Sql Server, always use query parameters. In fact, when sending any data, of any type, to Sql Server in an SQL statement, always use query parameters. Anything else will not only result in formatting issues like your problem here, but will also leave you crazy-vulnerable to sql injection attacks. If you find yourself using string manipulation to include data of any type into an SQL string from client code, step away from the keyboard and go ask a real programmer how to do it right. If that sounds insulting, it's because it's so hard to understate the importance of this issue and the need to take it seriously.
When retrieving dates from Sql Server, most of the time you should just select the datetime field. Let client code worry about how to format it. Do you want leading zeros? Great! The Sql Datetime column will at some point be available in C# as a .Net DateTime value, and you can use the DateTime's .ToString() method or other formatting option to convert the value to whatever you want, at the client.
SQL queries use a date and time format which goes like this:
2014-09-15
That's year-month-day. As per the comments below, this may be different depending on the collation you have on your database (see Scott's comment for a more accurate way to describe this and get dates into this format).
DateTime's ToString method has an overload which takes a formatting string. So you can pass the format you want the string to be output to. Try it like this:
string queryDate = from.ToString("yyyy-MM-dd");
And see what you get. Use that on your query.
But if you really want this done right, use parameters. Like:
SqlCommand command = new Command(connection, "SELECT * FROM foo WHERE someDate = #date");
command.Parameters.AddWithValue("#date", from);
// where "from" is your DateTime variable from the code you've shown.
This will save you the trouble of DateTime to String conversions.
I'm kind of in an awkward search and replace situation. I'm developing a new database for the my employer and am now at the process of importing old data into the new MySQL database. The issues I'm at crossroads with is that the old database was a LEGACY database by the name of PC-File which used .dbf files, so I found a dbf viewer that would allow me to export the information into a .csv file, but, one file in particular, has over 5000 records of data with incorrect century dates... instead of displaying 12/28/2012 - it will display 12/28/1998. I have searched up and the down the internet trying to find a way to parse the date information between the year ranges of "01/01/1900 - 01/01/1914" and replace the "19" with "20." And to no avail have I been able to find a successful solution.
I hope my question is clear is enough....
I'm open to solutions with excel, C#, vb.net, and MySQL; any input or advice would be GREATLY appreciated.
Here is a sample of my .CSV file:
"CUSTOMER","ORDER_DATE"
670,"4/18/1913"
670,"6/25/1913"
670,"6/25/1913"
667,"9/18/1912"
665,"9/14/1912"
664,"12/8/1920"
664,"12/8/1920"
658,"9/23/1911"
658,"2/6/1912"
655,"5/11/1911"
651,"12/10/1910"
651,"12/10/1910"
651,"12/14/1910"
648,"6/2/1910"
648,"6/2/1910"
648,"6/2/1910"
648,"6/2/1910"
Thank you guys for any feedback or tips.
If you've got it in a database run the following SQL
MySQL Solution:
update myTable
set ORDER_DATE = DATE_ADD(ORDER_DATE, INTERVAL 100 YEAR)
where ORDER_DATE between '1900-01-01' and '1914-01-01'; /* Change this cutoff date range as appropriate */
Whatever technology you use the logic's the same; select all records for which the date has the wrong year, then correct by adding 100 years.
The Excel solution would be:
=IF(AND(A1>=DATE(1900,1,1),A1<=DATE(1914,1,1)),DATE(YEAR(A1)+100,MONTH(A1),DAY(A1)),A1)
where column A contains your date values.
You should be able to just parse the dates any way you can, check if they're in the 1900-1914 range you specified, and replace the "19" with "20". Here's one way to handle the parsing and subsequent replacement with Regex:
string brokenDate = "648,\"12/10/1912\"";
System.Text.RegularExpressions.Match m = System.Text.RegularExpressions.Regex.Match(brokenDate, #"(\d{1,2}/\d{1,2}/)19(?=(0[0-9]|1[0-4]))");
string fixedDate = m.Groups[1].Value + "20" + m.Groups[2].Value;
You could also alter the Regex to return the whole line if you wanted, instead of just the fixed date as I've done. Or as someone else suggested, it should be possible to modify it a bit to just fix the whole file in one go.
I have a problem with inserting a date time from my web app, using C# to my database with SQL Server 2008.
My machine is set to Hebrew but I also tried to change to en-us culture. It's a conversion thing I know, but can't figure out how to pass it correctly.
In the database, the column is declared as DATE NOT NULL,
This is how I try to pass a date from C# by using a dataset:
newDR["Close_Date"] = Convert.ToString(this.closeDate.Date.ToString("YYYYMMDD"));
Any ideas?
Don't convert it to a string at all. Keep it as a DateTime. Try to avoid using string conversions as far as you can - every string conversion is a potential source of problems.
So:
newDR["Close_Date"] = closeDate.Date;