My pre-production task is to create tools to parse MySQL database schema and generate scripts to recreate it completely or partially. I've implemented first part of the task by fetching metadata from INFORMATION_SCHEMA tables and storing it in form of tree-like structure in memory. Now I'm busy generating scripts for each database objects. The issue I encountered is escaping Special Character Escape Sequences (as noted at this page, table 9.1) such as ' and " during writing string literals. Literals can be met in trigger and routine body or in SELECT part of view definition.
When I generate script for creating, say, trigger, literals with unescaped quotes corrupt the query and I cannot run it without manual correction. I get something like this.
Query with syntax error
I would like to be able to run my queries immediately after generating, so I need to write them with escaped quotes. I deviced two possible solution.
Fetch metadata of triggers, routines and views in the way that MySQL escape special sequences in literals. I've been browsing SO and docs for a while and yet to find an appropriate function on the MySQL side. (QUOTE() is not the case as it'll escape every escapable character in routine/trigger definition and even the ones that should not be escaped)
Escape that sequences manually just before script generating. I've tried to figure out the regexp to find and replace such units and here is what I got.
Pattern pattern = Pattern.compile("\'(.+)\'");
Matcher matcher = pattern.matcher("IF (NEW.AccountBalance <> 0 OR NEW.BlockedAmount <> 0) THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT='The account can't be closed!' END IF;");
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
sb.append("'").append(matcher.group(1).replace("'", "\\\'")).append("'");
}
System.out.println(sb.toString());`
Certainly, this will not work if you've got several literals as I have in my example. It'll escape all single quotes between first and last single quote character and turn two or more literals into one senseless string. I'm guessing is it's possible at all to do it on the app side as regex cannot know where the literal starts and ends. Only me and MySQL can.
I've tried Walid's regexp solution from here and it escaped all target characters in my string, even starting and ending quotes for literals.
I'd highly appreciate any advice how to do it on the app or MySQL side.
Related
Using Jooq generator, by Gradle plugin, I am getting now with POJOs and tables not only classes with normal names, bu also heaps of files whose names start by bin$.
They are not necessary, for only yesterday the generator did not make these files. And everything works OK with or without them. But I don't want the project to be littered with tens of excessive files.
Since 10'th version, Oracle puts the dropped tables to the recycle bin. They have names starting by Bin$. So, JooQ simply makes classes for dropped tables. That could be blocked in two ways: To stop use recycling bean in Oracle or to filter the tables for which the Jooq generator makes classes.
ALTER SYSTEM SET RECYCLEBIN = OFF DEFERRED;
purge dba_recyclebin;
or to change the generator setting (the example is for Gradle)
generator{
...
database {
...
excludes = '(?i:BIN\\$.*)'
Edit: Finally after several attempts (by Lukas) and checks (by me) Lukas had found the correct meaning for excludes. Its form, IMHO, has the only explanation - JOOQ doesn't work with regex'es correctly, for Groovy does not parse the strings in single quotes.
jOOQ's <excludes/> setting is a Java regular expression. You have to properly form it like this:
excludes = '(?i:BIN\\$.*)'
Explanation:
Use (?i:...) for case-insensitivity. Just in case. Pun intended.
Use \\ before the $ sign because the $ means "end of line" in regular expressions. You want to escape that. And because Groovy/Gradle parses (as in "look for escape sequences") your string, you need to escape the backslash too, for it to reach the Java Pattern.compile() call
Use .* to indicate that after the $, you want to match any number of characters. . = any character and * = any number of repetitions
I am fetching a String from SQL server 2008 database into my Java code and trying to print it. Unfortunately the newline escape sequence is not automatically converted into newline.
I know the reason is we are not putting the string inside the double quotes in the Database table. Below is the sample value stored in the varchar column :
Remarks \nTestRemarks Issue\nTestIssue\n\nRegards \nSunny
When I am printing it on log file it is printing along with \n. My application convention doesn't allow me to store String within double quotes inside Database varchar column, therefore I chose to explicitly unescape it using Apache StringEscapeUtils.unescapeJava(str). Unfortunately, the result is that 1st and last newline escape sequence is successfully converted to newlines, but rest all newline escapes remain unchanged. If I put space before the newline escape sequence in the DB, then it gets recognized and converted,but not otherwise. Can you please help how I solve this situation.
How about doing the opposite once you retrive it, ie StringEscapeUtils.escapeJava(str) or repeat StringEscapeUtils.unescapeJava(str) after you retrieve it from the database. Either one might work.
my setup is working in wierd manner. for some reason after system restart and eclipse restart and tomcat restart, everything seems to work seamlessly. closing the answer as non-issue
I have a table of project in which i have a project name and that project name may contain any special character or any alpha numeric value or any combination of number word or special characters.
Now i need to apply keyword search in that and that may contain any special character in search.
So my question is: How we can search either single or multiple special characters in database?
I am using mysql 5.0 with java hibernate api.
This should be possible with some simple sanitization of you query.
e.g: a search for \#(%*#$\ becomes:
SELECT * FROM foo WHERE name LIKE "%\\#(\%*#$\\%";
when evaluated the back slashes escape so that the search ends up being anything that contains "\#(%*#$\"
In general anything that's a special character in a string can be escaped via a backslash. This only really becomes tricky if you have a name such as: "\\foo\\bar\\" which to escape properly would become "\\\\foo\\\\bar\\\\"
A side note, please proof read your posts prior to finalizing. Its really depressing and shows a lack of effort when your questions title has spelling errors in it.
I am getting the following error after running the jsp report.
Query Tag:doAfterBody(),0,Non supported SQL92 token at position: 3477: S
I know that the following snippet causing the problem ‘{S}’:
…….. AND (L.Applicable_Location_Region_ID IN (N'PARIS2', N'{S}Paris2'))
As per my investigation, I came to know following:
Oracle parses the SQL and treats the text of "'{S}Paris2" as a string literal then finds {S} which it is treating as a SQL Escape Sequence which it doesn't recognize.
The following link explains well about “Escape Characters”:
http://docs.oracle.com/cd/F49540_01/DOC/inter.815/a67843/cqspcl.htm
we must use {S} followed by name.
The above AND statement works fine with SQL Server and MySQL, but causes problem with Oracle as “When you use braces to escape a single character, the escaped character becomes a separate token in the query.”
Due to above reason the application treats {S}, as the escaped a single character with braces becomes a separate token in the query.
So please could you help me how can I escape single character with braces in oracle or any suggestion please.
Try
AND (L.Applicable_Location_Region_ID IN (N'PARIS2', N'\{S\}Paris2'))
EDIT:
Running this query from Toad
select (N'{S}test2') from dual where ((N'{S}test2') IN (N'test2', N'{S}test2'))
does work for me.
Are you sure that the problem is in Oracle database and not in the class/driver accessing it ?
We are using Java and Oracle for development.
I have table in a oracle database which has a CLOB column in it. Some XYZ application dumps a text file in this column. The text file has multiple rows.
Is it possible that while reading the same CLOB file thru Java application, the escape sequences (new line chars, etc) may get lost??
Reason I asked this is, we gona parse this file line by line and if the escape sequences are lost, then we would be trouble. I would have done this analysis myself, but I am on vacation and my team needs urgent help.
Would really appreciate if you could provide any thoughts/inputs.
You need to ensure that you use the one correct and same character encoding throughout the whole process. I strongly recommend you to pickup UTF-8 for that. It covers every human character known at the world. Every step which involves handling of character data should be instructed to use the very same encoding.
In SQL context, ensure that the DB and table is created with UTF-8 charset. In JDBC context, ensure that JDBC driver is using UTF-8; this is often configureable by JDBC connection string. In Java code context, ensure that you're using UTF-8 when reading/writing character data from/to streams; you can specify it as 2nd constructor argument in InputStreamReader and OutputStreamWriter.
A CLOB stores character data. Carriage returns and line feeds are valid characters, though unprintable ones. As long as your XYZ app is correctly filling your CLOBs, the contents should be just as manageable to you as if they had come from the file.
Depending on the platform and the nature of said "XYZ app," lines could be separated by either \r(Mac), \r\n (DOS/Windows) or \n (Unix/Linux), and you should make allowance for this fact if necessary. This is one aspect where BufferedReader.readLine() is more convenient, as it transparently gets rid of this difference for you.
I'm not 100% sure what you mean by escape sequences in this context. Within a (for example) Java literal string, "\n" is an escape sequence representing a newline, but once that string is outputted into something (say, a database), it's not an escape sequence any more, it's an actual newline character.
Anyhow, to your direct question, Java through can read text from Oracle CLOBs perfectly fine. Newlines are not lost.