Jdbc compilation using Ant - oracle

I am using the following ant script for jdbc compilations.
<sql driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#10.184.133.133:1521:SUPP"
userid="${UsernameB}"
password="${PasswordB}"
onerror="continue"
delimitertype="row"
delimiter="/"
keepformat="yes">
I have a file with the following content:
create OR REPLACE synonym CIVWS for CIVW;
/
compilation of the above is failing with the following error.
java.sql.SQLSyntaxErrorException: ORA-00911: invalid character
I understand that the delimiter is / and hence the semi colon after the sql statement has caused the issue. There are hundreds of files like this, all will compile properly in sqlplus. However fail with jdbc. I cant change the code now. Is there any work around for this. I cant change the delimiter to ; also. Please suggest.

first you could try to use ... delimiter=";" delimitertype="row" ... and make sure that the pl/sql blocks containing ";"s are separated by some ";" on a single line (with only a newline following it immediately - thus triggering the execution of it as a single statement).
if you can't add the ";" by hand, try to copy the source files to some tmp dir and try to change them there by hand or by some automated regexp replacement (e.g. using ant copy task with a regexp replace filter).
(e.g. replacing lines matching ^(.*end\s*;?)(.*)$ by \1\n;\n\2 could be enough if you are lucky)
another solution for inserting the ";"-single line delimiters could be to put these blocks in separate files (maybe automated) and execute them via the <sql><transaction src="<yoursqlfile>.sql" /> <!--...--> </sql> <!--...-->" ANT task.

Related

How to handle improper Data Coming from CSV in Informatica

I have source file (CSV) and need to load into target (Oracle). But I got an error
FR_3065 ROW[4],Filed [Student_rollnumber]:Invalid Number:[.].The row will be skipped
CSV TABL
Student_rollnumber,Studnet_Name,Marks,Subjects
10,'Revanth',70,"Maths",
11,'Satish',85,Science
12,'Anil',75,"Java
",
13,'Surya',90,"C++",
14,'Ramana',85,"python",
15,'Sudheer'70,"Informatica
",
16,'Prakash',85,"SQL"
I found that in line number 4 the qouts and comma(",) are in the next line how to concat that both ("Java",) And make it single column(Subject)
MatchQuotesPastEndOfLine mentioned by Koushik should work.
Alternatively you may use sed with below pattern to replace newline+" with simply just a " - as a result removing the new line at the end of quoted string.
sed ':a;N;$!ba;s/\n"/"/g'
Feel free to test this gist.
This however will remove just the ending new line and will not help if it's anywhere in the middle. As said, the MatchQuotesPastEndOfLine mentioned by Koushik is the best possible solution.
Above has been based on this question.

SED Ensure XML insert not inside comment

I am working with stock RHEL7/8 tools, and writing a script that will add a piece to a config file that is formatted as XML. I have run into a case where my sed statement can insert the added text inside a comment.
My current sed command gets the last existence of the tag <Program> and inserts the new tag after its closing tag </Program>.
How can I account for this possibly, but not always being inside a comment?
My script:
sed -i '0,/<Program id/s// <Program id=\"myProgram\"> <\/Program>' filepath
XML Example (displays the error inserting inside comment):
<Program id="myProgram"></Program>
<!--
<Program id="commentedOutProgram"></Program>
<Program id="newlyAddedProgram"><Program>
-->
EDIT:
This is happening at install time. I would like to add a way for some RHEL 7/8 built in tool to look in the XML file, make sure it's not in a comment, and add the new contents
Have a go with this. The usual caveats apply: It probably only works for exactly the sample you provided. Use a proper XML tool if you need a robust solution.
sed -e '/<!--/,/-->/b' \
-e '0,\%<Program id="[^"]*"></Program>%s%<Program id="myProgram"> </Program>%' filepath
Your original script seemed to have several errors, so I couldn't copy it verbatim, but this should at least give you an idea of how to modify it: add a b to skip any lines between <!-- and -->.
The % separators are just to avoid having to backslash slashes; sed allows you to use any separator you like instead of a slash, you just have to backslash the first one.
The b command jumps to a label; if the label is not specified, it jumps to the end of the script, i.e. skips the substitution part and starts over with the next line. The address expression before b selects any comment region, i.e. any lines between a line matching <!-- and a line matching -->.

Compilation issue with JDBC under Apache Ant

I am using the following specification for JDBC compilations using Ant.
<sql driver="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:#10.184.133.133:1521:SUPP"
userid="${UsernameB}"
password="${PasswordB}"
onerror="continue"
delimitertype="row"
delimiter="/"
keepformat="yes">
The delimiter here is slash (/). If there are spaces after the slash the compilation is not happening properly. Is there any way I can avoid this situation?
I assume you mean that if you have a space after the slashes separating the SQL statements it won't compile?
I suggest you add
strictDelimiterMatching="false"
which force recognition of the delimiter to be case-insensitive (which is irrelevant here) and to ignore surrounding whitespace.

Is it possible to run a SQLPLUS script on a file encoded as UTF-8 with BOM

I'm trying to run a collection of scripts which have been auto-generated from a large number of sources. Unfortunately some of these have been generated as UTF-8 with BOM. I have in place a system for automatically removing the BOM, but its a bit of a messy process.
Failing to remove the BOM generates the error:
SP2-0042: unknown command "" - rest of line ignored.
Is it possible to run SQLPLUS on a script file which has a BOM?
It is possible to run SQLPLUS with such script, but SQLPLUS will indicate an error on the first line because of BOM.
Probably you wanted to ask if you can avoid this error - it is not possible, AFAIK. Erwin thinks so too.
You can workaround losing any information by generating those files with an empty first line. Then you can just ignore this error.
This has been a bug open with Oracle for over 6 years now, but it doesn't look like they are interested in fixing it.
Their 'recommended workaround' (Doc ID 788156.1 Section C.6) is to strip the BOM or make your first script line a comment, and then ignore this error.
SP2-0042: unknown command "" - rest of line ignored.
Or
SP2-0734: unknown command beginning "-- Commen..." - rest of line
ignored.
Bug 13515585 Details (requires OTN login):
Bug 13515585: ADD SUPPORT FOR THE UTF-8 BOM IN SQLPLUS
Bug Status: Internal (Oracle) Review
Created: 19-Dec-2011
Updated: 29-Sep-2015

How does Pig use Hadoop Globs in a 'load' statement?

As I've noted previously, Pig doesn't cope well with empty (0-byte) files. Unfortunately, there are lots of ways that these files can be created (even within Hadoop utilitities).
I thought that I could work around this problem by explicitly loading only files that match a given naming convention in the LOAD statement using Hadoop's glob syntax. Unfortunately, this doesn't seem to work, as even when I use a glob to filter down to known-good input files, I still run into the 0-byte failure mentioned earlier.
Here's an example: Assume I have the following files in S3:
mybucket/a/b/ (0 bytes)
mybucket/a/b/myfile.log (>0 bytes)
mybucket/a/b/yourfile.log (>0 bytes)
If I use a LOAD statement like this in my pig script:
myData = load 's3://mybucket/a/b/*.log as ( ... )
I would expect that Pig would not choke on the 0-byte file, but it still does. Is there a trick to getting Pig to actually only look at files that match the expected glob pattern?
This is a fairly ugly solution, but globs that don't rely on the * wildcard syntax appear to work. So, in our workflow (before calling our pig script), we list all of the files below the prefix we're interested, and then create a specific glob that consists of only the paths we're interested in.
For example, in the example above, we list "mybucket/a":
hadoop fs -lsr s3://mybucket/a
Which returns a list of files, plus other metadata. We can then create the glob from that data:
myData = load 's3://mybucket/a/b{/myfile.log,/yourfile.log}' as ( ... )
This requires a bit more front-end work, but allows us to specifically target files we're interested and avoid 0-byte files.
Update: Unfortunately, I've found that this solution fails when the glob pattern gets long; Pig ends up throwing an exception "Unable to create input slice".

Resources