Strange syntax in a Where clause - sql-server

The following is a simplied version of a query that a reporting tool is sending to our database. I have never seen this syntax before in the Where clause. Can someone tell me what the brackets are doing? And, I assume the 'd' acts as a date cast?
Select
ch.ContainerID,
ch.WorkItemHistoryEventTypeEnumID,
ch.EventTime,
ch.ContainerBinName,
ch.WorkItemSerialNumber,
ch.Closed
From Wip.vwContainerHistory ch
Where
ch.EventTime >= {d '2010-08-09'}

See "Supported String Literal Formats for datetime" section in MSDN datetime article.
Your {d 'XXXX-XX-XX'} is ODBC datetime format. ODBC timestamp escape sequences are of the format: { literal_type 'constant_value' }:
literal_type specifies the type of the escape sequence. Timestamps have three literal_type specifiers:
d = date only
t = time only
ts = timestamp (time + date)
'constant_value' is the value of the escape sequence. constant_value must follow these formats for each literal_type.
d > yyyy-mm-dd
t > hh:mm:ss[.fff]
ts > yyyy-mm-dd hh:mm:ss[.fff]

This is an ODBC escape sequence for a date type. See http://msdn.microsoft.com/en-us/library/ms187819.aspx
d = date only
t = time only
ts = timestamp (time + date)

Related

invalid input syntax for type timestamp

While running the below code i get an error saying invalid input syntax for type timestamp from admission_datetime.
UPDATE ccsm.stg_demographics_baseline
SET xx_los_days =
(CASE WHEN admission_datetime IS NULL OR
date_trunc('day',admission_datetime) = ''
THEN NULL
WHEN discharge_datetime IS NULL OR
date_trunc('day',discharge_datetime) = ''
THEN date_diff('day', admission_datetime, CURRENT_DATE)
ELSE
date_diff('day', admission_datetime, discharge_datetime)
END);
enter code here
See date_trunc documentation:
The return value is of type timestamp or interval with all fields that are less significant than the selected one set to zero (or one, for day and month).
So you can not compare it with an empty string:
date_trunc('day', admission_datetime) = ''
The invalid input syntax for type timestamp error message concerns the empty string (''), not the admission_datetime column.
Furthermore, there is no date_diff function in PostgreSQL. Just subtract one timestamp from another and you will get an interval result:
SELECT timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00'
You'll get
interval '1 day 15:00:00'
If you need the difference in days, try this:
SELECT DATE_PART('day', timestamp '2001-09-29 03:00' - timestamp '2001-09-27 12:00')
The result is 1.
See here for examples of DATEDIFF-like expressions in PostgreSQL.

convert string date to date type in sql server 2012

In a school website, I want to enable the admin to filter students based on date range when they were born. Dates in my tblStudent are stored as strings, so I cannot use:
SELECT ts.Name from tblStudent ts WHERE ts.BirthDay>'1367/01/31' AND ts.BirthDay<'1377/01/31'
I have saved dates (Jalali Format) in database table tblStudent. I need to do comparison based on dates. So I need to convert date strings to date type in sql server. To this purpose I used:
SELECT convert(date,tblStudent.BirthDay) from tblStudent
However,It stops after 27 results with the following error
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
I have the following date strings in my tblStudent table.
1379/09/01
1375/04/20
1378/03/02
1378/03/21
1378/04/18
1378/04/18
1378/05/05
1375/04/20
1379/01/03
1378/03/01
1370/09/09
1378/03/22
1375/09/15
1379/09/01
1379/09/10
1375/04/08
1375/05/06
1370/09/09
1379/10/10
1375/04/10
1375/11/01
1375/04/04
1375/08/11
1375/05/05
1376/09/19
1375/12/12
1376/01/13
1375/15/10
1375/04/14
1375/04/04
1375/05/14
1374/11/11
1375/05/30
1375/05/14
1377/12/13
1377/02/31
1377/12/14
1377/01/13
1375/05/31
1377/11/05
1377/07/05
1375/05/31
1377/03/01
1377/04/01
1377/05/02
1377/05/04
1377/03/03
1377/01/14
1377/05/30
1377/04/31
1375/05/30
1376/06/12
1375/12/10
1377/08/14
1377/03/04
1375/04/08
1375/07/18
1375/08/09
1375/09/12
1375/11/12
1376/12/12
1375/01/02
1375/05/09
1375/04/09
1376/01/01
1375/01/30
1377/04/04
1375/05/23
1375/05/01
1377/02/01
1367/12/05
1375/05/31
1373/03/29
1373/03/03
1375/05/05
Is there a way to convert these string dates to date type and then compare them with some query? For example, such a query can be:
SELECT ts.Name from tblStudent ts where ts.BirthDay>'1375/05/31'
I think you can make them ints and compare them:
SELECT ts.Name
FROM tblStudent ts
WHERE CONVERT(INT,REPLACE(ts.BirthDay,'/','') > 13670131
AND CONVERT(INT,REPLACE(ts.BirthDay,'/','') < 13770131
Or for your second example:
SELECT ts.Name
FROM tblStudent ts
WHERE CONVERT(INT,REPLACE(ts.BirthDay,'/','') > 13750531
This would work because having the order Year-Month-Day will ensure that the int representation of a later time will be greater than the int representation of an earlier time.
I really do not know if this is the best idea, but it is an idea of how to do it. After all you would be using a conversion.
From C# you have a few options:
If your input is string:
var dateInt = Int32.Parse(dateString.Replace("/",""));
If your input is Date then:
var dateInt = Int32.Parse(dateValue.ToString("yyyyMMdd"));
You could also pass the string itself in the db and let the db do the work for you :
DECLARE #Date AS VARCHAR(10)
SET #Date = ...--This will be filled with the inputed string
DECLARE #DateINT AS INT
SET #DateINT = CONVERT(INT,REPLACE(#Date,"/",""))

NancyFX not serializing dates with a trailing Z to indicate UTC/Zulu

We store all of our dates in our database as UTC.
When they are returned to us from the API, they are in the following format
"createdDate":"2014-07-30T18:34:45"
But as you can see, the date doesn't have the trailing Z (which indicates to our Angular app that it's UTC / Zulu). It should look like this
"createdDate":"2014-07-30T18:34:45Z"
I do have the following setting in our Bootstrapper
JsonSettings.ISO8601DateFormat = true;
Where in my config can I ensure that there's a trailing Z for the purpose of UTC parsing?
What version of NancyFx are you using? Because in v0.23.0 or later, the JsonSerializer code has been changed to use the "o" date format instead of the "s" date format, which should give you the trailing Z that you're looking for. (But only on UTC datetimes.)
This is the commit that made this change. Note how DateTimeKind.Unspecified dates are treated as local; that might be one possible cause of your problem, if you're not explicitly creating your DateTime objects as DateTimeKind.Utc.
Below is the NancyFx code that serializes DateTime values, as it looks as of v0.23.0 (after that commit). From https://github.com/NancyFx/Nancy/blob/v0.23.0/src/Nancy/Json/JsonSerializer.cs, lines 480-518:
void WriteValue (StringBuilder output, DateTime value)
{
if (this.iso8601DateFormat)
{
if (value.Kind == DateTimeKind.Unspecified)
{
// To avoid confusion, treat "Unspecified" datetimes as Local -- just like the WCF datetime format does as well.
value = new DateTime(value.Ticks, DateTimeKind.Local);
}
StringBuilderExtensions.AppendCount(output, maxJsonLength, string.Concat("\"", value.ToString("o", CultureInfo.InvariantCulture), "\""));
}
else
{
DateTime time = value.ToUniversalTime();
string suffix = "";
if (value.Kind != DateTimeKind.Utc)
{
TimeSpan localTZOffset;
if (value >= time)
{
localTZOffset = value - time;
suffix = "+";
}
else
{
localTZOffset = time - value;
suffix = "-";
}
suffix += localTZOffset.ToString("hhmm");
}
if (time < MinimumJavaScriptDate)
time = MinimumJavaScriptDate;
long ticks = (time.Ticks - InitialJavaScriptDateTicks)/(long)10000;
StringBuilderExtensions.AppendCount(output, maxJsonLength, "\"\\/Date(" + ticks + suffix + ")\\/\"");
}
}
As you can see, requesting ISO 8601 date format will get you the 2014-07-30T18:34:45 format rather than the number of milliseconds since the epoch, but it will assume local times if the value being serialized has a Kind equal to DateTimeKind.Local.
So I have two suggestions for you: upgrade to v0.23 of NancyFx if you're still on v0.22 or earlier (v0.22 used the "s" date format, which does not include timezone info, for serializing DateTime values). And if the DateTime objects you're serializing aren't explicitly set to DateTimeKind.Utc, then make sure you specify Utc (since the default is Unspecified, which NancyFx treats as equivalent to Local).

sql server date in the format yyyy-MM-ddThh:mm:ssZ

I need to format a set of dates in SQL server to the following format..
yyyy-MM-ddThh:mm:ssZ
I cant seem to find how to format the date with the T and Z parts included in the string
Any ideas how to achieve this format in a SQL query?
According to the SQL Server 2005 books online page on Cast and Convert you use date format 127 - as per the example below
CONVERT(varchar(50), DateValueField, 127)
SQL Server 2000 documentation makes no reference to this format - perhaps it is only available from versions 2005 and up.
Note on the time zone added to the end (from note 7 in the docs): The optional time zone indicator, Z, is used to make it easier to map XML datetime values that have time zone information to SQL Server datetime values that have no time zone. Z is the indicator for time zone UTC-0. Other time zones are indicated with HH:MM offset in the + or - direction. For example: 2006-12-12T23:45:12-08:00.
Thanks to Martin for this note: You should be able to use STUFF to remove the miliseconds as these will be in a fixed position from the left of the string. i.e.
SELECT STUFF(CONVERT(VARCHAR(50),GETDATE(), 127) ,20,4,'')
DECLARE #SampleDate DATETIME2(3) = '2020-07-05 23:59:59';
SELECT CONVERT(VARCHAR(20), CONVERT(DATETIMEOFFSET, #SampleDate), 127);
--results: 2020-07-05T23:59:59Z
You can parse C# output in SQL using below:
SELECT CONVERT(DATETIME, CONVERT(DATETIMEOFFSET,'2017-10-27T10:44:46Z'))
Use C# to generate this using the following:
string ConnectionString = "Data Source=SERVERNAME; Initial Catalog=DATABASENAME; Persist Security Info=True; User ID=USERNAME; Password=PASSWORD";
using(SqlConnection conn = new SqlConnection(ConnectionString))
{
DateTime d = DateTime.Now;
string Query = "SELECT CONVERT(DATETIME, CONVERT(DATETIMEOFFSET,'" + d.ToString("yyyy-MM-dd") + "T" + d.ToString("HH:mm:ss") + "Z'))"
conn.Open();
using(SqlCommand cmd = new SqlCommand(Query, conn))
{
using(SqlDataReader rdr = cmd.ExecuteReader())
{
if(rdr.HasRows)
{
while(rdr.Read())
{
for(int i; i < rdr.length; i++)
{
Console.WriteLine(rdr[0].ToString());
}
}
//DataTable dt = new DataTable(); dt.Load(rdr); //Alternative method if DataTable preferred
}
}
}
}
select left(convert(varchar(30),getdate(),126)+ '.000',23)
Try this
SELECT STUFF(
CONVERT(datetime2(0), GETDATE(), 126)
AT TIME ZONE 'US Eastern Standard Time'
,11,1,'T')
on MSSQL
SELECT FORMAT( GETDATE(),'yyyy-MM-ddTHH:mm:ss.ms zzzz')

Error using to_char // to_timestamp

I have a database in PostgreSQL and I'm developing an application in PHP using this database.
The problem is that when I execute the following query I get a nice result in phpPgAdmin but in my PHP application I get an error.
The query:
SELECT t.t_name, t.t_firstname
FROM teachers AS t
WHERE t.id_teacher IN (
SELECT id_teacher FROM teacher_course AS tcourse
JOIN course_timetable AS coursetime
ON tcourse.course = coursetime.course
AND to_char(to_timestamp('2010-4-12', 'YYYY-MM-DD'),'FMD') = (coursetime.day +1)
)
AND t.id_teacher NOT IN (
SELECT id_teacher FROM teachers_fill WHERE date = '2010-4-12'
)
ORDER BY t.t_name ASC
And this is the error in PHP
operator does not exist: text = integer (to_timestamp('', 'YYYY-MM-DD'),'FMD') =
(courset... ^ HINT: No operator matches the given name and argument type(s).
You might need to add explicit type casts.
The purpose to solve this error is to use the ORIGINAL query in php with :
$date = "2010"."-".$selected_month."-".$selected_day;
SELECT ...
AND to_char(to_timestamp('$date', 'YYYY-MM-DD'),'FMD') = (coursetime.day +1)
)
AND t.id_teacher NOT IN (
SELECT id_teacher FROM teachers_fill WHERE date = '$date'
)
The error message seems quite clear to me. You are mixing strings and numbers. More precisely, you are converting a string ('2010-4-12') to a timestamp, then to a string, then comparing to an int. This is a type mess, and postgresql is quite strict with typing (for good reasons). What are you trying to do here ?
to_char(to_timestamp('2010-4-12', 'YYYY-MM-DD'),'FMD') = (coursetime.day +1))
Further, you should use a TIMESTAMP, just a DATE.
If (I'm not sure) you are tring to compare the day of week from a date formated as 'YYYY-MM-DD' to a given value (as an integer), you should better use date_part. For example (not tested):
date_part('dow' , to_date('2010-4-12', 'YYYY-MM-DD') ) = coursetime.day + 1

Resources