C, unixODBC, oracle and Date queries - c

I've got a query like
select x from tableName where startDate <= now;
When i query the database without the date fields, everything works as expected. As soon as i start using date or timestamp columns in the oracle Database, my queries return nothing or an error.
What I do:
snprintf(sql, sizeof(sql), "SELECT roomNo, userPass, adminPass, adminFlags, userFlags, bookId, is_locked, running_on_server FROM booking WHERE roomNo = '?' AND startTime <= { ts '?' } AND endTime >= { ts '?' } for update;");
stmt = ast_odbc_prepare_and_execute(obj, generic_prepare, &gps);
the ? will be replaced by values, with following command:
SQLBindParameter(stmt, i + 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(gps->argv[i]), 0, gps->argv[i], 0, NULL);
when I execute the query I get an error that TS is an invalid identifier [this was a recommendation by another board, taken from msdn - which may cause this error]
but even if I remove it and send just a string to the database, I'll get an empty result back. I also tried to bind the parameters as SQL_TIMESTAMP and SQL_DATE, but this didn't help either.
Hopefully somebody can help me.
thanks in advance.
Chris

Are you sending a DATE data type to the Oracle query or a date represented in a string?
From the Oracle side of things, if you send a date in a string variable you'll need to use the oracle "TO_DATE" function (http://www.techonthenet.com/oracle/functions/to_date.php) to then convert thew string back to a date for use in your SQL statement (assuming startDate or startTime/endTime are DATE columns in the database).
Your fist SQL example should be:
SELECT x
FROM tableName
WHERE startDate <= TO_DATE(now, '<date-format>');
If the variable "now" was a string containing '05-OCT-2011 16:15:23' (including a time portion) then the to_date would be:
TO_DATE(now, 'DD-MON-YYYY HH24:MI:SS')
If you compare a string with a date and don't specify the format of that date Oracle will use its default NLS parameters and try to apply that format. Therefore it is always prudent to specify the date format using TO_DATE.
Hope it helps...

Related

Date and/or time from character string error message

SELECT communication.*
,employeedetails.resourcename
FROM communication
,employeedetails
WHERE employeedetails.employeenumber = communication.employeenumber
AND communication.project = employeedetails.projectname
ORDER BY
CONVERT(DATETIME ,communication.month ,5)
I am getting the following error message:
"Conversion failed when converting date and/or time from character
string"
Kindly help me out
It is not easy having no info regarding the data tables involved!
However if names are meaningful, how can you convert a month to a datetime?
If it is existing try this:
SELECT communication.*, employeedetails.resourcename
FROM communication, employeedetails
WHERE employeedetails.employeenumber = communication.employeenumber and communication.project = employeedetails.projectname
ORDER BY communication.day, communication.month, communication.year --due to style 5
even if I would suggest to go for style 12
The datatype of communication.month is presumably a character type. If this holds "January" for January etc. then SQL has no way of converting that character to a datetime. You would need to append a string such that SQL could parse it as a datetime.
e.g. ORDER BY CONVERT(datetime,communication.month + '01 2000',5).
However, storing the communication date as a datetime in the first place would be better...

What should be a default datetime value?

I am inserting Excel Sheet records in my DataTable in c# and passing this DataTable to an SQL stored procedure. In my c# code I have put certain checks for empty data cells of Excel sheet to avoid Exceptions. But It seems like I am missing something while giving a default value for my SQL Date field.
string InvoiceDate = (row.Cells[3].Text == " ") ? "0/00/0000 00:00:00 AM" : (row.Cells[3].Text);
And I get the following error:
String was not recognized as a valid DateTime.Couldn't store
<0/00/0000 00:00:00 AM> in InvoiceDate Column. Expected type is
DateTime.
Edited -
Declaration of SQL field [InvoiceDate]
[InvoiceDate] [date] NOT NULL
Please don't suggest inserting null as I cannot Insert null for this column.
First, There is no 00/00/0000 date, not in the real world and not in sql server.
Second, why do you even need a default values? just use null instead.
Third, use ISO 8601 format for specifying dates in strings (yyyy-mm-ddThh:mm:ss)
Forth, As Giorgi rightfully pointed out in his comment, why even use strings for a datetime value? use a variable of type DateTime in c#. note that it's min value is different then the sql server DateTime data type min value.
If your datetime column is not nullable, you can use 1753-01-01 (min value for datetime) or 9999-12-31 (max value for datetime)
One last thing, you might want to consider using either datetime2 or separate the date and time to different columns (data types date and time, of course). Why? read here.
Try to insert the current date instead:
string InvoiceDate = string.IsNullOrEmpty(row.Cells[3].Text) ? DateTime.Now.ToString() : (row.Cells[3].Text);

How to convert MySQL to SQL Server query to display proper date from timestamp?

I need the following query below converted for SQL Server 2005, so please let me know what I should change since SQL Server doesn't support DATE_FORMAT()
How it should look converted in SQL Server so I can display proper date on my website instead of timestamp (example: 1382016108 to be 2013-06-22 10:53:22) ?
SELECT DATE_FORMAT(TimeTransfer,'%Y-%m-%d %h:%i:%s')
FROM PREMIUM where strAccountID = ?, $_SESSION['strAccountID']);
EDIT: I checked the CONVERT() function but couldn't find out how it should be exactly in my case with my query. Help is greatly appreciated.
This will work:
SELECT CONVERT( VARCHAR(20) -- Make sure the output string is long enough
, CAST('1970-1-1' As DateTime) -- The Base Date
+ CAST(TimeTransfer As Float)/(24*60*60)
-- Scale UTC (seconds) to TSQL datetime (days)
-- by dividing by the number of seconds in a day
, 120) -- The format that you want
Check the Convert function. It allows you to give format to a datetime value
SELECT CONVERT(VARCHAR(20),TimeTransfer,120)
FROM PREMIUM
WHERE strAccountID = ?, $_SESSION['strAccountID']);
Use CONVERT() function
SELECT CONVERT(varchar(20),TimeTransfer,120)
FROM PREMIUM where strAccountID = ?, $_SESSION['strAccountID']);
Note : This gives time in 24 hour format
See this link for Date formats in SQL Server

Allow Search for Invalid Date stored as string - Is it recommended or not

I have two tables for an Entity - say Valid_Doc and Invalid_Doc. If document is valid, then all the data gets saved in Valid_Doc table.In case any of the attribute of document is invalid , it gets saved in Invalid_Doc.Due_Date is on of the column of both the tables. In Invalid_Doc , we are saving Invalid dates as string.
Suppose if user searches for documents through a SEARCH screen with following date
Due_Date - is after - 07/07/11,
Shall we show all the documents from both the tables.As Due_Date in Invalid_Doc table is string, there is no way we can compare the entered search date with the dates available in database in Invalid_Doc table.
Can someone please guide me whether to use DATEDIFF - i.e. need to convert the String date in DB to Date(millisecs) first and then do the comparison with the entered data.Doing this , there may be unpredictable results. So , shall we allow the user to search for Invalid doc through Date or NOT.
Select * FROM invalid_doc iil WITH (nolock) WHERE
CAST(Datediff(s, '19700101 05:00:00:000', iil.due_date) AS NUMERIC) *
1000
BETWEEN '1120501800000' AND '1120501800000'
Where '1120501800000' and '1120501800000' are Date converted in milliseconds.
Please suggest.
I would convert the dates in the database to a uniform string format using regex (eg. Q20011231Q) and also convert the query to the same format before searching.
This way you would have control on your data and can easily do comparisons
I continue as answer :)
As I don't know your language you handle the xml data I strongly suggest you validate you date befor you insert into your database.
It is not possible to enter a non valid data value into a datatime field.
if you have a data like 11/24/2011 and insert it, the datetime value always add the time itself.
Then you have eg. 11/24/20011 17:29:00 000 as value stored.
If you insert less then a date it might crash or if the value can be converted to a valid date, the missing parts will be replaced by "current date information".
So in fact you have to validate you string, convert it. Something like this:
-- #datestring <= somehow your string from xml
SET arithabort arith_overflow OFF
SET #date = CAST(#datestring AS DATETIME)
IF #date is NULL SET #date = GETDATE()
SET arithabort arith_overflow ON
You turn overflow error mode off, try convert and set default if it fails.
Or in MS SQL
IF ( ISDATE(#date_string) = 0 ) SET #date = GETDATE()
Hope this helps

Date parameter not evaluated correctly when using ADO and SQL Server

I have the following SQL statement:
SELECT 420, DueDate, ISNULL(Amount, 0)
FROM Payments
WHERE CurveID = ? AND DueDate >= ?;
which I am executing using Delphi 2010 and TADODataset. The statement executes correctly except that the evaluation of the clause DueDate >= ? is not correct. If I pass in Date() or Now() for second parameter I get values returned with dates earlier than today in the DueDate field.
In SSMS, I can run this SQL query successfully if I replace the date parameter with a string in the format '2011-09-09' like this:
SELECT 420, DueDate, ISNULL(Amount, 0)
FROM Payments
WHERE CurveID = 19 AND DueDate >= '2011-09-09';
However, back in Delphi, even if I set my parameter value to a stringified version of the date in this format, I get the incorrect results (presumably because TADODataset is correctly converting the string back into a date).
What must I do, short of building dynamic SQL with the date hard-coded into the SQL to get this to evaluate correctly?
Use (named) parameters, something like
Query.CommandText := 'SELECT 420, DueDate, ISNULL(Amount, 0) FROM Payments '+
'WHERE CurveID = :CurveID AND DueDate >= :DueDate';
Query.Prepared := True;
Query.Parameters.ParamValues['CurveID'] := 19;
Query.Parameters.ParamValues['DueDate'] := EncodeDate(2011, 9, 9);
Query.Active := True;
This also allows you to set the type of the parameter should the system not to get it right, ie
Query.Parameters.ParamByName('DueDate').DataType := ftDate;
Note also that ParamCheck property of the ADODataSet must be true (default) in order to use :name style parameters.
Please try this:
AND DueDate >= CONVERT(datetime,?);
Are the regional settings different between the Delphi client and the SQL Server? This can cause invalid dates to be returned. Though I admit that if month = year as in "9/9/2011", that should not matter.
We had issues like this using a French Canadian C# client talking to a US-English database server. The client formatted April 1, 2011 as '1/4/2011' which the database interpreted as January 4, 2011.
Zero date is not same in OS and DB , 01/01/1900 v/s 30/12/1899. You need to +/- 2 days depending on select/update.
Here is the solution to my problem:
I was using TADOCommand to execute the SQL against the database (not TADODataset as I mistakenly wrote in the question, oops). Switching to TADOQuery solved the problem. The execute SQL interface is different between the two classes and TADOQuery unequivocally looks at the Parameters property of the dataset for it's parameters. TADOCommand has a Parameters property, but also accept an array of Parameter as an argument to the .Execute() method.
With TQuery my parameters are correctly typed without additional effort on my part. This works with position or named parameters.
Something I've noticed is the difference in behaviour between assigning ParamByName and ParamValues using Delphi TDateTime values
var
MyDate: TDateTime
AdoQuery1.ParamByName('DueDate').AsDateTime := MyDate // works with US English
//vs
AdoQuery1.ParamValues['DueDate'] := MyDate // works with various date formats
There is no differences when your ShortDate Settings are English US, but when they are not, ParamByName does not do the conversion correctly for all settings.
ParamValues does the conversion correctly. I'm guessing that the conversion code for variants is "better" than the conversion between Delphi TDateTime values and ADO DateTime values - which is why I have moved away from using ParamByName in my applications.

Resources