Having greater than or less than in hibernate named sql query - sql

I'm using hibernate 3 with named query in the hibernate configuration xml.
The named query originally matched a date with the user entered date, and it worked fine.
But when I changed the equals ('=') to a less than ('<=') it gave me the following error.
Caused by: org.hibernate.MappingException: Could not parse mapping document in input stream
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:431)
at org.hibernate.cfg.Configuration.addResource(Configuration.java:482)
... 106 more
Caused by: org.dom4j.DocumentException: Error on line 57 of document : The content of elements must consist of well-formed character data or markup. Nested exception: The content of elements must consist of well-formed character data or markup.
at org.dom4j.io.SAXReader.read(SAXReader.java:482)
at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:422)
... 107 more
This is because the XML parser does not allow '<' or '>' inside the content of tags. But '<' or '>' is necessary to form the <= or >= comparison. Is there an alternate way to represent greater than or less than such that the parser is happy.
NB: I already know we can put the named query as annotation in the code, but I prefer it this way for system consistency.
Sample Named Query:
<sql-query name="persons">
<return alias="person" class="eg.Person"/>
SELECT person.NAME AS {person.name},
person.AGE AS {person.age},
person.SEX AS {person.sex}
FROM PERSON person
WHERE person.NAME LIKE :namePattern
AND trim(person.JOINDATE) <= to_date(:joinDate, 'dd-mm-yyyy')
</sql-query>

Use CDATA or < to escape < in xml.

Related

Is there a way to make the mapping dynamic loop between the XML scheme?

Setuing a fix engine for Bloomberg FXGO for FX Derivatives.
Although using an XML scheme (DataDictionary=FIX_BBG.xml) for the mapping of the FIX message, I receive an error of
*FIX Message": "8=FIX.4.4|9=156|35=3|34=1770|49=MAP|52=20220118-14:39:48.607|56=MAP_BBG_BETA|145=FX|45=1783|**58=Out of order repeating group members, field=602|371=602|372=8|373=15|10=180"***
This due to the fact that the tags sequence is repeating across different type of transactions;
For the above tag 602 is coming in normal sequence and then repeats itself after tag 675.
Is there a way to make the mapping dynamic loop between the XML scheme?
Tried to add the tag 602 in multiple location in XML scheme or changing the order but still receiving the same error
Adding a sample FIX msg, 602 tag to 1074 in the sequence is repeating twice, whereas in the XML schema is once and in arithmetic order from 1 to 20,XXX tag. and this is resulting to rejection.
8=FIX.4.4|9=2317|35=8|49=MAP_BLP_BETA|56=MAP_BETA|34=1933|144=FX|52=20220708-15:01:49|30=XOFF|60=20220708-14:55:49.210|120=USD|150=F|31=1.203294|151=0|32=240003|64=20220719|6=1.203294|1056=288794.17|37=3-2-XXXXXXXXXXX-0-0|1057=Y|38=240003|218=0|39=2|40=G|460=4|1300=XOFF|1390=0|11=3-2-XXXXXXXXXXX-0-0|14=240003|194=1.2032|854=0|15=GBP|75=20220708|195=0.000593|17=3-2-XXXXXXXXXXX-0-0|167=FXSWAP|797=Y|22277=0|48=TGBYHN1234|528=P|22280=2|22=4|54=B|55=GBP/USD|119=288794.17|2489=FX_CASH_RFQ_815676229|78=2|79=TESTVENUE|80=240003|79=TESTVENUE|80=240003|555=2|**600=GBP/USD|****1788=1|602=TGBYHN1234|603=4****|607=4|609=FXFWD|624=1|556=GBP|687=240003|654=1|587=6|588=20220719|675=USD|637=1.203294|1073=0.000094|1074=288794.17|****600=GBP/USD|1788=2|602=EZBCKS7MP4D1|603=4|607=4|609=FXFWD|624=2|556=GBP|687=240003|654=2|587=6|588=20220812|675=USD|637=1.203887|1073=0.000687|1074=288936.49|**10009=6|10010=VENUE1|10011=1.203334|22161=1.203927|22162=0.000593|22163=0.000687|22485=1.20324|22486=0|22545=0|10010=VENUE2|10011=1.203304|22161=1.203897|22162=0.000593|22163=0.000687|22485=1.20321|22486=0|22545=0|10010=VENUE3|10011=1.203324|22161=1.203917|22162=0.000593|22163=0.000687|22485=1.20323|22486=0|22545=0|10010=VENUE5|10011=0|22161=0|22162=0|22163=0|22485=0|22486=0|22545=0|10010=MidRate|10011=1.20324|22161=1.203845|22162=0.000605|22163=0.000695|22485=1.2032|22486=0|22545=0|10010=RefRate|10011=1.203294|22161=1.203887|22162=0.000593|22163=0.000687|22485=1.2032|22486=0|22545=0|22078=1|22079=1.203294|22080=20|22081=12|453=7|448=XOFF|447=G|452=64|802=1|523=TESTUIT12345678|803=4025|448=BGTB|447=D|452=13|802=5|523=Pricer Test USER4|803=1|523=24876081|803=2|523=USER1|803=9|523=12345QAZWSX|803=4025|523=Y|803=4047|448=125698745|447=P|452=12|2376=24|802=1|523=Y|803=4047|448=125698745|447=P|452=122|2376=24|802=1|523=Y|803=4047|448=VENUE2|447=D|452=1|802=5|523=Pricer BGAU|803=1|523=27391323|803=2|523=TESTUSER|803=9|523=12345QAZWSX|803=4025|523=Y|803=4046|448=PRODUCT TYPE|447=D|452=16|802=1|523=Dealing (RFQ)|803=4|448=24876081|447=D|452=11|1907=2|1903=TESTUTI2333333|1905=1234QWERT|1904=0|1906=5|2411=1|1903=TESTID12345667789|1905=1234QWERT|1904=0|1906=5|2411=2|768=2|769=20220708-14:55:49.210|770=1|769=20220708-14:55:40.000|770=10|2668=2|2669=0|2670=4|2669=1|2670=7|10=243|

Escaping ? (question mark) in hibernate/gorm sql restriction

I'm attempting to query against a materialized path stored with postgres ltree type from a Grails application. Unfortunately, my query uses the "?" operator which is being captured by GORM as a parameter
sqlRestriction("materialized_path ? (SELECT ARRAY(SELECT CAST(CAST(subpath(?,0,generate_series) AS text) ||'.*{1}' AS lquery) FROM generate_series(1,nlevel(CAST(? AS lquery)))))"
,[vertex.materializedPath,vertex.materializedPath])
Where that first question mark should be escaped and the error being thrown is
org.postgresql.util.PSQLException: No value specified for parameter 4.
at org.postgresql.core.v3.SimpleParameterList.checkAllParametersSet(SimpleParameterList.java:246)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:272)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:430)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:356)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:168)
at org.postgresql.jdbc.PgPreparedStatement.executeQuery(PgPreparedStatement.java:116)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:70)
Found it myself with a little experimentation. It just takes a double-question mark. So,
"materialized_path ? (SELECT ARRAY(...
becomes
"materialized_path ?? (SELECT ARRAY(

Searching date and time in Lucene query string in Cloudant

I am trying to write the index and search using date and time in that index in Cloudant NoSql database.
When I pass only the date in the query string, it works fine
created_date:[2015-08-16 TO 2015-08-27]
This returns the correct results but when I include time in the parameter:
created_date:[2015-08-16 07:38:00 TO 2015-08-27 07:38:02]
I get an error:
Cannot parse 'created_date:[2015-08-16 07:38:00 TO 2015-08-27 07:38:02]': Encountered " "TO" "TO "" at line 1, column 50. Was expecting one of: "]" ... "}"
I have some more query parameters before this but the above is the gist of the error.
This is an Apache Lucene query string. What is causing this to happen?
According to Lucene Java doc, date format should looks like this:
A date field shall be of the form 1995-12-31T23:59:59Z The trailing
"Z" designates UTC time and is mandatory
This format was derived to be standards compliant (ISO 8601) and is a
more restricted form of the canonical representation of dateTime from
XML schema part 2. Examples...
1995-12-31T23:59:59Z 1995-12-31T23:59:59.9Z 1995-12-31T23:59:59.99Z
1995-12-31T23:59:59.999Z
So, you miss 'T' between date and time.
For more information: https://lucene.apache.org/solr/4_10_4/solr-core/org/apache/solr/schema/DateField.html
I did it the following way
created_date:["2015-08-16 07:38:00" TO "2015-08-27 07:38:02"]
and used the keyword analyzer in cloudant
This link explains it all
https://lucene.apache.org/core/2_9_4/queryparsersyntax.html

How to make LIKE in SQL look for specific string instead of just a wildcard

My SQL Query:
SELECT
[content_id] AS [LinkID]
, dbo.usp_ClearHTMLTags(CONVERT(nvarchar(600), CAST([content_html] AS XML).query('root/Physicians/name'))) AS [Physician Name]
FROM
[DB].[dbo].[table1]
WHERE
[id] = '188'
AND
(content LIKE '%Urology%')
AND
(contentS = 'A')
ORDER BY
--[content_title]
dbo.usp_ClearHTMLTags(CONVERT(nvarchar(600), CAST([content_html] AS XML).query('root/Physicians/name')))
The issue I am having is, if the content is Neurology or Urology it appears in the result.
Is there any way to make it so that if it's Urology, it will only give Urology result and if it's Neurology, it will only give Neurology result.
It can be Urology, Neurology, Internal Medicine, etc. etc... So the two above used are what is causing the issue.
The content is a ntext column with XML tag inside, for example:
<root><Location><location>Office</location>
<office>Office</office>
<Address><image><img src="Rd.jpg?n=7513" /></image>
<Address1>1 Road</Address1>
<Address2></Address2>
<City>Qns</City>
<State>NY</State>
<zip>14404</zip>
<phone>324-324-2342</phone>
<fax></fax>
<general></general>
<from_north></from_north>
<from_south></from_south>
<from_west></from_west>
<from_east></from_east>
<from_connecticut></from_connecticut>
<public_trans></public_trans>
</Address>
</Location>
</root>
With the update this content column has the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Physicians>
<name>Doctor #1</name>
<picture>
<img src="phys_lab coat_gradation2.jpg?n=7529" />
</picture>
<gender>M</gender>
<langF1>
English
</langF1>
<specialty>
<a title="Neurology" href="neu.aspx">Neurology</a>
</specialty>
</Physicians>
</root>
If I search for Lab the result appears because there is the text lab in the column.
This is what I would do if you're not into making a CLR proc to use Regexes (SQL Server doesn't have regex capabilities natively)
SELECT
[...]
WHERE
(content LIKE #strService OR
content LIKE '%[^a-z]' + #strService + '[^a-z]%' OR
content LIKE #strService + '[^a-z]%' OR
content LIKE '%[^a-z]' + #strService)
This way you check to see if content is equal to #strService OR if the word exists somewhere within content with non-letters around it OR if it's at the very beginning or very end of content with a non-letter either following or preceding respectively.
[^...] means "a character that is none of these". If there are other characters you don't want to accept before or after the search query, put them in every 4 of the square brackets (after the ^!). For instance [^a-zA-Z_].
As I see it, your options are to either:
Create a function that processes a string and finds a whole match inside it
Create a CLR extension that allows you to call .NET code and leverage the REGEX capabilities of .NET
Aaron's suggestion is a good one IF you can know up front all the terms that could be used for searching. The problem I could see is if someone searches for a specific word combination.
Databases are notoriously bad at semantics (i.e. they don't understand the concept of neurology or urology - everything is just a string of characters).
The best solution would be to create a table which defines the terms (two columns, PK and the name of the term).
The query is then a join:
join table1.term_id = terms.term_id and terms.term = 'Urology'
That way, you can avoid the LIKE and search for specific results.
If you can't do this, then SQL is probably the wrong tool. Use LIKE to get a set of results which match and then, in an imperative programming language, clean those results from unwanted ones.
Judging from your content, can you not leverage the fact that there are quotes in the string you're searching for?
SELECT
[...]
WHERE
(content LIKE '%""Urology""%')

How to preserve an ampersand (&) while using FOR XML PATH on SQL 2005

Are there any tricks for preventing SQL Server from entitizing chars like &, <, and >? I'm trying to output a URL in my XML file but SQL wants to replace any '&' with '&'
Take the following query:
SELECT 'http://foosite.com/' + RTRIM(li.imageStore)
+ '/ImageStore.dll?id=' + RTRIM(li.imageID)
+ '&raw=1&rev=' + RTRIM(li.imageVersion) AS imageUrl
FROM ListingImages li
FOR XML PATH ('image'), ROOT ('images'), TYPE
The output I get is like this (&s are entitized):
<images>
<image>
<imageUrl>http://foosite.com/pics4/ImageStore.dll?id=7E92BA08829F6847&raw=1&rev=0</imageUrl>
</image>
</images>
What I'd like is this (&s are not entitized):
<images>
<image>
<imageUrl>http://foosite.com/pics4/ImageStore.dll?id=7E92BA08829F6847&raw=1&rev=0</imageUrl>
</image>
</images>
How does one prevent SQL server from entitizing the '&'s into '&'?
There are situations where a person may not want well formed XML - the one I (and perhaps the original poster) encountered was using the For XML Path technique to return a single field list of 'child' items via a recursive query. More information on this technique is here (specifically in the 'The blackbox XML methods' section):
Concatenating Row Values in Transact-SQL
For my situation, seeing 'H&E' (a pathology stain) transformed into 'well formed XML' was a real disappointment. Fortunately, I found a solution... the following page helped me solve this issue relatively easily and without having re-architect my recursive query or add additional parsing at the presentation level (for this as well for as other/future situations where my child-rows data fields contain reserved XML characters): Handling Special Characters with FOR XML PATH
EDIT: code below from the referenced blog post.
select
stuff(
(select ', <' + name + '>'
from sys.databases
where database_id > 4
order by name
for xml path(''), root('MyString'), type
).value('/MyString[1]','varchar(max)')
, 1, 2, '') as namelist;
What SQL Server generates is correct. What you expect to see is not well-formed XML. The reason is that & character signifies the start of an entity reference, such as &. See the XML specification for more information.
When your XML parser parses this string out of XML, it will understand the & entity references and return the text back in the form you want. So the internal format in the XML file should not cause a problem to you unless you're using a buggy XML parser, or trying to parse it manually (in which case your current parser code is effectively buggy at the moment with respect to the XML specification).
Try this....
select
stuff(
(select ', <' + name + '>'
from sys.databases
where database_id > 4
order by name
for xml path(''), root('MyString'), type
).value('/MyString[1]','varchar(max)')
, 1, 2, '') as namelist;