ant sql insert statement fails on '--' strings. workaround? - sql

Context
We're changing our install scripts to use ant's "sql" task and jdbc rather than proprietary sql clients sqlplus (oracle) and osql (msft).
Updated: added more context. Our "base data" (seed data) consists of a collection of .sql files containing "vendor-neutral"(i.e. works both in oracle and mssql) sql statements.
The Problem
The scripts run fine, with one exception:
This sql fails in Oracle. Specifically, something (ant or jdbc driver) treats the dashes/hyphens as "beginning of a comment"--even though they are embedded in a string. Note that the same sql works fine with ant/sql and microsoft's jdbc driver.
INSERT INTO email_client (email_client_id,generated_reply_text) VALUES(100002,'----- Original Message -----');
Related Bug
This ant bug appears to identify the problem. As it's still open (after 8 years), I'm not hoping for a fix soon. However, because the problem appears only in oracle, it may lie with the driver.
The oracle driver: jdbc thin driver, version 10.2.0.1.0
The Question
Does anyone have a workaround which works in both mssql and oracle? (e.g. changing the offending lines to define an escape character? I don't see an 'escape' on the 'insert' sql92 syntax)
thanks

After viewing the 'SQLExec' source and turning on verbose logging, I found a workaround:
Workaround
if the sql statement includes a string containing '--', place the delimiter (semi-colon) on the next line.
This Fails
INSERT INTO email_client (email_client_id,generated_reply_text) VALUES(100002,'----- Original Message -----');
This Succeeds
Note that semi-colon is on a separate line
INSERT INTO email_client (email_client_id,generated_reply_text) VALUES(100002,'----- Original Message -----')
;
Details
Turning on verbose logging, I saw that when Ant came across the offending sql statement, it actually passed three sql statements in at once to the jdbc driver. The offending statement, the next statement (which also included an embedded '--'), and the subsequent statement (which did not include an embedded '--').
I gave the Ant code a quick glance and didn't see any obvious errors. Since I wasn't planning to patch Ant, I looked for a workaround.
Tweaking with it I found that if I simply moved the delimiter (semicolon) to the next line for the statements with embedded '--', the scripts executed successfully.
thanks everyone for weighing in

You could try this:
INSERT INTO email_client (email_client_id,generated_reply_text)
VALUES(100002,LPAD('-',5,'-') || ' Original Message ' || LPAD('-',5,'-'));

Related

Install4j: SQL Script and statement delimiter

I try to run several SQL-Statements in an SQL Script action for an Oracle dbms inside an installer and as part of a JDBC container action.
The script is encoded as UTF-8, and contains several statements, delimited by ";" and a new line between each statement, like this
statement 1;
statement 2;
...
The statements contain installer variables that are replaced before execution. I used the semicolon as a statement separator in the SQL script action.
The first statement throws an error
Error executing script line "CREATE user testconuser identified by xxx TEMPORARY TABLESPACE temp;",
error message: "ORA-00911: invalid character"
The statement itselfs works fine within SQLPLUS, but the problems seems to be the semicolon, that is still part of the statement executed by install4j.
In a JDBC sql statement, semicolons are not valid.
I also tried to remove the semicolons from the statements and used "\n" as statement delimiter, but then the sql script actions fires all sql statements within the script at once, so it looks like the "\n" is not recognized.
I am using install4j 6.1.5 build 6349. The platform is windows and the sql script is build on windows.
Any idea what I should change?
Any help would be highly appreciated, thanks a lot in advance,
Alex
I used the semicolon as a statement separator in the SQL script action. The first statement throws an error Error executing script line
and
I also tried to remove the semicolons from the statements and used "\n" as statement delimiter
Both are bugs in 6.1.5 and will be fixed in 6.1.6. Please contact support#ej-technologies.com to get a build where you can verify that this will work for you.

PostgreSQL Driver Appends Hidden Characters On Some SQL Statements

I have an application that I am building (Spring Boot, PostgreSQL); I am executing sql statements from a file sqlStatements.sql against the database. In some instances, it appears that the driver is appending a white-space character to the front of insert statements and when trying to create a function, it does not occur when defining tables though. I used the trim() method on the sql string to no avail. When logging the sql statements, there is no white-space character, but when looking at the PostgreSQL logs, sure enough, it's there. Is this a known issue with the driver? Is there a setting on the database side I need to change? Or do I need to do extract work in Java to avoid this error?
The space disappeared when pasting it here, so I added it; the sql files are all UTF-8.
Application log:
org.postgresql.util.PSQLException: ERROR: syntax error at or near
"insert" Position: 1
PostgreSQL log:
2017-03-04 10:29:26 EST ERROR: syntax error at or near " insert" at
character 1
Any feedback would be appreciated.
the file encoding was different between the various sql files. I had to set the encoding to "UTF-8" instead of "UTF-8 with BOM".
https://apple.stackexchange.com/questions/46586/textedit-removes-byte-order-mark-bom-from-unicode-utf-files-how-to-fix

Oracle SQL Developer - Ctrl+Enter runs whole worksheet instead of current line

I am using Oracle SQL Developer 4.0.3.16, and since a few weeks, the shortcut Ctrl+Enter doesn't execute the current line or statement anymore, except for when I highlight it, but instead does run my whole worksheet. Using the green button on the top, which is supposed to only run the current line results in the same behaviour (except for when the line is highlighted). Hovering over the button still reveals the tooltip "Run Statement (Ctrl+Enter)". A colleague of mine does get this problem too.
I also looked into the Preferences->Shortcut Keys menu, but the shortcut set for running a statement is still Ctrl+Enter.
Anyone knows what's wrong with my SQL Developer?
Every SQL statement in SQL Developer should have semicolon ; otherwise ctrl+Enter would execute will execute entire worksheet.
Suppose for example I have two SQL statements:
1.select * from emp without semicolon ;
2.UPDATE EMP SET DEPT_ID=10; WITH SEMICOLON ;
Then it will execute both statement simultaneously for that you should have semicolon after each SQL statement.
I faced it too. Usually you'll have PL/SQL block above the SQL code you are trying to execute. Comment out the PL/SQL block which is DECLARE, BEGIN without ending in semicolon creating this issue. So commenting the PL/SQL block in worksheet should solve your issue.
Thanks to the answer here: if it doesn't work even with a semicolon after the line like it didn't for me (Oracle SQL Developer 3.2.20.10), you need to put a '/' after each command if you want to execute them all independently, e.g.:
blahblah;
/
blahblah;
/
Think of the '/' as the real terminator/separator here.
I think I kinda solved it.
Since I'm not an administrator on the computers at work I couldn't install a new client, so I downloaded the SQL Developer in version 4.0.3.16 a while ago and just ran it locally from my user directory.
Meanwhile the client 4.0.3.16 is installed on the OS and when using this client I don't get this bug.
Thanks for the help though.

Same code executed on different servers (same version) yields different results

Issue with Delphi legacy code. Added one line of code to correct one error and created a new error.
New error is causing the same executable to yield different results on different servers(switched the pointer from dev to prod environment on the executable).
code:
sEscapedString:=stringreplace(sStringIn,'[','''+char(27)+''[',[rfReplaceAll]);
sEscapedString:=stringreplace(sEscapedString,']','''+char(27)+'']',[rfReplaceAll]);
sEscapedString:=stringreplace(sEscapedString,'''','''''',[rfReplaceAll]);// this line created new
bug
result:=' like ''' + Trim(sEscapedString) + '%'''+' escape char(27) ';
When running the code against dev this query finds objects with the characters '[' and ']' in it
Against prod the query does not find those items:
The first thing I checked was the data: Exactly identical in both cases
The second thing I checked was SQL server versions (11.0.3128 on BOTH servers)
The third thing I am checking is settings on those servers:
DBCC USEROPTIONS; -- same on both
SELECT name, collation_Name FROM sys.databases -- same on both
select ##OPTIONS -- same on both.
Quoted identifiers are 'ON' for both servers
It comes down to the fact that I know one server is treating the escape character (chr(27)) differently than the other but I do knot know why.
Does anyone have a theory(or answer) as to why the 2 similar servers are treating the escape characters differently?
The goal here is getting the prod server to return values with '[' and ']', as setting up my system to work with the legacy code will take a LOT of additional time. I do have a fix for the code
sEscapedString:=stringreplace(sStringIn,'[','[[]',[rfReplaceAll]);
But the faster option would seem to be getting the server to read the values the same.
Update: We found the root cause of the difference and it was more mundane than what we expected, turns out the query we were running was actually executed twice. The second execution was missing the key piece on the production server.
The issue was resolved by moving the new line of code so that it executed first rather than last.
I would first try to find out if this SQL only causes different behaviour when it is sent from the application: by sending the SQL from an interactive SQL client tool to both servers.
To make sure that the manually tested SQL is exactly the same as in the application, I would try to log or capture the exact SQL as sent from the application as a text file and then paste its content to the SQL client tool.
If the server is the culprit, then using the SQL from a different client tool should cause the same difference with the two servers. If the client tool shows the same (correct) result on both servers, then something is going on in the Delphi application.
p.s. upvoted, it is an interesting phenomenon

Is the semicolon necessary in SQL?

Sometimes it works anyway if I forget the ;. But sometimes it doesn't.
And in JDBC and Android SQLite, it seems that I don't need ; at all. I am confused.
When should I use a semicolon?
semicolon indicates end of a statement, so if there are multiple statements then you should use semicolon else it will work fine.
I generally use semicolon as a practice, it can be useful even when you are running queries on sql client e.g. in Sql Developer using semicolon is very helpful if you have multiple statements on worksheet, as you can simply go to that particular statement and use F9 to execute that, without semicolon this is not possible.
It is not mandatory if you run a single query at time, it comes necessary instead if you want to run multiple query with a single command.
However in most of JDBC drivers out there it is not possible to add multiple query separated with semicolon in a single JDBC Command, it exist however the addBatch method that allow you to add multiple statements :
java.sql.Statement stmt=con.createStatement();
stmt.addBatch(insert_query1); //insert_query1
stmt.addBatch(insert_query2); //insert_query2
As a rule of thumb, in JDBC semicolon is not necessary at all, if you need multiple statement use addBatch.
Usually the semicolon is not part of the actual syntax of a statement (as most database internal APIs execute a single statement at a time). Instead the semicolon is an 'end-of-statement' marker or statement separator that is - usually - defined in CLI or scripting tools for the database. This allows that tool to know when a statement ends, so it can send that single statement to the database for execution.
On the other hand, the JDBC API is intended to execute a single(!) statement at a time, therefore you don't need such a separator (the statement is the whole string). This means that a semicolon is not needed, and as it is not part of the actual statement syntax for a lot of database it is also a syntax error to include it. Some JDBC drivers will strip the last ; from a statement to 'fix' that, some drivers don't.
Some drivers allow - contrary to the JDBC specification - multiple statements to be executed as a single string, this usually has to be enabled with a connection property, for example for MySQL it is the option allowMultiQueries (see the MySQL properties for details).
Depends on the DBMS and version number. Semicolons are often optional at the end of a single statement. But if you are going to execute a script with more than one statement, they need to be terminated by a semicolon.
Except maybe the last one. But it seems bad form to be inconsistent.