XWiki - format date inside the query - sql

I need to compare two dates. One is an attribute of a page, the second is a current date. The problem is, they're not in the same format and so XWQL cannot compare them (I think it's because of the first date). But, I don't know how can I change the format of the first date to be acceptable by Query Module.
I see no way how could I use $datetool, because I need to reformat the date during the execution of the query, not before it ( I don't have the content of the attribute ).
I'd love to find some function like MySQL date_format(). I use XWQL now, but the query can also be written in HQL.
So, do you know any way to do this?
Example:
FROM doc.object('$xcontext.macro.params.parentSpaceClass')
AS page
WHERE :validDate >= $currDate
ORDER BY $ordCol $xcontext.macro.params.orderDirection
validDate - the NAME of the attribute, not its value ( for example page.enddate )
Date formats:
validDate - 01/10/2014 14:47:08
$currDate - Thu Nov 06 12:27:50 EET 2014

You can not use query parameters to fill in actual subjects of the query. It will just use the literal string 'page.enddate' as a value for the comparison, and no matter what value and in which format you put $currDate, it will not perform the right comparison.
You should pass the $currDate as a parameter as well, don't just append it in the query.
The actual query you end up with is:
FROM doc.object('Some.Class') AS page
WHERE 'page.endddate' >= Thu Nov 06 12:27:50 EET 2014
ORDER BY ...
That literal date isn't quoted, so it will trigger a syntax exception. Even quoted, dates have their own syntax in SQL. Fortunately, the XWiki query module knows how to convert Java dates into the proper format, if you pass the date as a parameter.
Try this:
$services.query.xwql("FROM doc.object('$xcontext.macro.params.parentSpaceClass')
AS page WHERE $validDateProperty >= :date ORDER BY $ordCol $xcontext.macro.params.orderDirection").bindValue('date', $currDate).execute()
```

Related

SQL Server Not Casting String YYYYMMdd to Date

I have a query that was working fine before a server migration and now is not working. I'm trying to convert all dates to a specific month and year, but I keep getting this error:
Conversion failed when converting date and/or time from character string.
Looking into the data, there are no null values in InputDate, which is a date data type column. When I run the Concat() function everything is formatted as 'YYYYMMdd', yet both CAST and CONVERT fail with the same error.
Is there an issue with my query that I'm not seeing?
SELECT RandoSTUFF,
DATEADD(day,2,CAST(CONCAT('2023','02',FORMAT(InputDate,'dd')) AS date)) AS MovedDate
FROM a_table_
I expect the issue is you have date values near the end of their months, and you're trying to compose the equivalent values for February, which is shorter.
So if you have an InputDate value of, say, 2022-12-31 and run the code in the question, it will extract the 31 and concat it with the other values, and you'll end up trying to do this:
CAST('20230231' as Date)
Of course, there is no such date.
As it is, it's not clear whether you want such an input to map to February 28 or March 3. To fix this, you'll need to rethink the problem so you only try to map to valid dates, and ensure the final result is more clearly defined. This is one of the many reasons it's almost always better to use Date/time functions instead of composing dates from strings.

how to search for a date row in sql?

I create column in this way:
ALTER TABLE cages
ADD test date;
I add date to this column
for instance
'01/07/21'
and when I use like always select:
select *
from cages
where test = '01/07/21';
I get nothing, it's weird, because in different table it's works... Can it connection with pk or fk or what is the reason of this?
edit:
I use SQL orlace developer.
edit:
thanks everyone for help, problem was that I used calendar to put date to column and it add date with time.
Why is it possible, when I have type date not dateTime?
Not everyone formats date values the same way. When looking at a date like 01/07/21, most of the people on this site will naturally read January 7, 2021*. The group that reads this as July 1, 2021 (today) is significant, but still slightly smaller. A few people come from cultures where July 21, 2001 is the natural interpretation.
To avoid this kind of ambiguity, when writing date literals for SQL you should always format them using the ISO-8601 formats, which always uses four digit years, goes in sequence from most significant term on the left to least significant term on the right, and always uses leading zeroes to fill out the full width of a term:
yyyy-MM-dd HH:mm:ss.fff
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
yyyyMMdd (unseparated version of the format preferred on Sql Server for date-only values for historical reasons)
Anything else is wrong for SQL.
For completeness, I also want to key in on the word "literals" from the beginning of the second paragraph. We should always use parameterized queries/prepared statements when putting date values into a query from a client code language, rather than using string manipulation to substitute a literal into the SQL command. On strongly typed platforms this usually means using the DateTime type provided by the language to set the value. If you find yourself converting a datetime variable to a string for inclusion in an SQL query, you're making a mistake.
* This isn't just a blind assertion. A few years back I did a basic review of the public portion of the Stack Overflow developer survey, where I first looked up which countries/languages default to which date formats, and then grouped countries together based on their format. I wish I had saved the results :/. I forget how I treated places with mixed heritage like Canada.
Your root problem, and I'm amazed no one seems to have picked up on this, is that your column is a DATE but in your query you are comparing it to a STRING. This may or may not work, depending on your NLS_DATE_FORMAT setting. You need to compare like data types:
select *
from cages
where test = to_date('01/07/21','dd-mm-yy');
I leave it as an exercise for the student to go to the SQL Reference manual and read up on the TO_DATE function.
I also beg and plead with you to not be trying to use 2-digit years. As an industry we were supposed to have solved that problem over 20 years ago. Does the term "Y2k bug" not mean anything to you?
As it is, the date that is represented by the string '01/07/21' could be understood to be any of the following
Jan 7
Jan 21
Jul 1
Jul 21
And who knows the year? 2021? 1921? 1821? 2001? 1901? 2007? 1907?, 1807?
You might want to read this.
Using SQL Developer if you insert a date in a table using user interface it automatically generates hours and minutes like if it's a Timestamp. If the format you are using is correct you should be able to retrieve your rows using like operator instead of equal.
select * from cages where test like '01/07/21%';
The only way to retrieve your rows using equal operator is when the timestamp is set to 00:00:00
1st July 2021 is written date '2021-07-01' in Oracle SQL.
You can read more about literals in the Oracle SQL Reference.
You can also use a to_date expression like
to_date('2021-07-21','YYYY-MM-DD')
or
to_date('1-Jul-21', 'DD-Mon-YY', 'nls_date_language = English')
or indeed
to_date('1-Lug-21', 'DD-Mon-YY', 'nls_date_language = Italian')
but frankly, why would you?
Bear in mind that that the person running the query/report/procedure, or the application server in use, may not have the same territory and language settings as you, so it is dangerous to assume that the century for a 2-digit year will always be what you expect (what year is '50'?) or the language will always be English, or the week always starts on a Monday. I worked on a system once where we deployed some code that used 'DD-MON-YYYY', to offices in London and Paris. We deployed it in September, and we had a production issue in Paris in February, because Sep, Oct, Nov, Dec and Jan still worked, but French has no Feb.

Conversion of Date for direct sql query in OBIEE using presentation variable

I am trying to achieve this use case: when there is no date picked I want to show all the results but when I have date picked I want it to filter.
fyi:
the date getting picked are YYYY-MM-DD HH24:MI:SS in the presentation variable, but the date format in my query is dd-mon-yy. So when I need to convert the value of the presntation varible to dd-mon-yy.
OBIEE doesnt like when I play around with the values, and the BI server does not let me look at the error message.
I dont have access to change the format on the server level so my only option is to use formulas
I'm new to presentation variable.
ALso I need you'll to remember if there is no date selected in the prompt I would want all values returned
code:
and
( ( main_query.schd_compare >= (#{pv_task_sch_st_date}['#']{NVL(main_query.schd_compare,'None')})
)
AND (
main_query.schd_compare <= (#{pv_task_sch_end_date}['#']{NVL(main_query.schd_compare,'None')})
) )
I need help with syntax for obiee
Inside the database, it doesn't care if a date is "DD Mon YY" or "YYYY-MM-DD HH24:MI:SS". Those are just formatting, and the actual bit value of that date will be the same. So if both "dates" are actually a date datatype, then you can just use something like:
....
AND (
(
main_query.schd_compare >= NVL(pv_task_sch_st_date,main_query.schd_compare)
)
AND
(
main_query.schd_compare <= NVL(pv_task_sch_end_date,main_query.schd_compare)
)
)
That's if your pv_task_sch_???_date are passed as NULL values when not selected. Oracle does seem to treat empty strings and NULL the same in comparisons like this, but you it can be hard to debug if you get in the habit of relying on NULL and '' being the same.
As for your query, my guess is that your pv_task... values are actually being passed to your query as a some sort of string. If that's the case, then you'll need to put a TO_DATE() around your pv_task... variables.
Take a look at https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=2066b2005a22769e785815f6b03750a1. I stepped through a few examples of how your dates can be treated.
I did say earlier that the database doesn't care when format your date is in. And it is stored the same, no matter the format. But when you're using TO_DATE() or other similar functions, Oracle wants you to specify the proper mask of your data. If you send "01 Jan 99" to TO_DATE(), Oracle needs to know how to interpret that value. So you tell it that the string is "DD Mon YY". You can't do TO_DATE('2018-09-10','YYYY-MM-DD HH24:MI:SS') because my input doesn't have a time component. ( I would also caution about using 2-digit years. )
By the way, I hate dates. And dealing with dates in Oracle reinforces that hatred.

Date format on query different from date format in result

I wrote a SQL query to have the results from 2016 Apr 01 to 2016 May 01.
When I wrote:
where a.DateIntervention >= '2016-04-01'
and a.DateIntervention < '2016-05-01'
I obtain the results from 2016 Jan 04 00:00:00.000, so it is reading my dates as ydm, although the results show the date format as ymd (2016-01-04 00:00:00.000)
And when I ask the system about the date format it tells me it is dmy (!)
How to change this setting so that I can write my queries like ymd and continue obtaining the results like ymd?
In SQL Server, you don't need to. If you drop the hyphens then the strings will be interpreted using YYYYMMDD:
where a.DateIntervention >= '20160401' and a.DateIntervention < '20160501'
I prefer the hyphens because they are more readable, accepted in most databases, and generally work in SQL Server. There are particular settings where they don't work, but 'YYYYMMDD' is always interpreted as a date.
I should add, you can throw in a cast()/convert() if you like:
where a.DateIntervention >= cast('20160401' as date) and
a.DateIntervention < cast('20160501' as date)
There's no built-in way for the query to realize "I was supplied a YMD date, I should output dates as YMD too.".
In theory you could call SET DATEFORMAT ymd, but I mislike that because it might affect something farther down the line you don't know about.
If you want an explicit formatting/parsing style during conversion (which is almost always a good idea), you need to explicitly convert it, and supply the style:
-- 126 is hyphenated, but has extra parts if something other than date is used
CONVERT(DATE, '2017-07-28', 126)
Of course, the best option is to supply the parameter as an actual DATE type, and get output the same way, which saves you from converting back and forth to a string type, and avoids the formatting problem. This may not be available in a cases, however (like ad hoc queries).

SQL between vs >= startdate and <= enddate

I'm writing some SQL queries in PL/SQL that require me to filter the records based on date. The field is a date/time type, but since I don't really care about the time I figured I'll just omit it from my where clause.
So I'm writing something like
WHERE
f.logdate between to_date('2011/01/01', 'yyyy/mm/dd') and
to_date('2011/01/31', 'yyyy/mm/dd')
To get all the records for january. I read that this is supposed to be equivalent to
WHERE
f.logdate >= to_date('2011/01/01', 'yyyy/mm/dd') and
f.logdate <= to_date('2011/01/31', 'yyyy/mm/dd')
But my final results are not what I expected: there are less records when I use the BETWEEN keyword than when I explicitly state the bounds. Is it because my assumption of what BETWEEN does is wrong?
EDIT: ah nvm, it appears that the date is not the issue. There was a subquery that I was using that was filtering its result set by date as well and was specifying date/time while I'm not.
Could you show the type of the "logdate" field (the sql create sentence could help) ?
In some databases the date type is actually a datetime field, so if you are looking for dates after "Jan 01 2011", you are really looking for dates after "Jan 01 2011 12:00:00 p.m.".
It may be your case.
if the time is set to 0:00 or something strange like that it wont work properly.
The query retrieves the expected rows because the date values in the query and the datetime values stored in the RateChangeDate column have been specified without the time part of the date. When the time part is unspecified, it defaults to 12:00 A.M. Note that a row that contains a time part that is after 12:00 A.M. on 1998-0105 would not be returned by this query because it falls outside the range.
http://msdn.microsoft.com/en-us/library/ms187922.aspx