how to insert a giant geometry into a field of type SDO_GEOMETRY? - oracle

I am trying to insert this http://pastebin.com/cKXnCqx7 geometry into an SDO_GEOMETRY field, as follows:
declare
str clob = http://pastebin.com/cKXnCqx7
begin
INSERT INTO TEMP_TEST_GEOMETRY VALUES (SDO_CS.TRANSFORM (SDO_GEOMETRY (str, 4674), 1000205));
end;
And is generating the following error:

The maximum size of a string literal is 32K in PL/SQL. You're trying to assign a 98K+ literal, which is what is causing the error (although since that refers to 4k, that seems to be from a plain SQL call rather than the PL/SQL block you showed). It isn't getting as far as trying to create the sdo_geometry object from the CLOB.
Ideally you'd load the value from a file or some other mechanism that presents you with the complete CLOB. If you have to treat it as a literal you'd have to manually split it up into chunks; at least 4 with this value if you make them large:
declare
str clob;
begin
dbms_lob.createtemporary(str, false);
dbms_lob.append(str, 'POLYGON ((-47.674240062208945 -2.8066454423517624, -47.674313162 -2.8066509996, <...snip...>');
dbms_lob.append(str, '47.6753521374 -2.8067875453, -47.6752566506 -2.8067787567, -47.6752552377 -2.8067785117, <...snip...>');
dbms_lob.append(str, '-47.658134547 -2.8044846153, -47.6581360233 -2.8044849964, -47.6581811229 -2.8044926289, <...snip...>');
dbms_lob.append(str, '-47.6717079633 -2.8057792966, -47.6717079859 -2.80577931, -47.6717083252 -2.8057795101, -47.6718125136 -2.8058408619, -47.6719547186 -2.8059291721, -47.6719573483 -2.8059307844, -47.6719575243 -2.8059308908, -47.6719601722 -2.8059324729, -47.6720975574 -2.8060134925, -47.6721015308 -2.8060157903, -47.6721017969 -2.8060159412, -47.6721058088 -2.806018171, -47.6721847946 -2.8060611947, -47.6721897923 -2.8060650985, -47.6722059263 -2.8060767675, -47.6722070291 -2.8060775047, -47.6722416572 -2.8060971165, -47.6722428566 -2.8060976832, -47.6722611616 -2.8061055189, -47.6722666301 -2.8061076243, -47.6722849174 -2.806116847, -47.6722862515 -2.8061174528, -47.6723066339 -2.8061257231, -47.6723316499 -2.8061347029, -47.6723426416 -2.8061383836, -47.6723433793 -2.8061386131, -47.672354519 -2.8061418177, -47.6723803034 -2.8061486384, -47.6725084039 -2.8061908942, -47.6725130545 -2.8061923817, -47.6725133654 -2.806192478, -47.6725180423 -2.806193881, -47.6728423039 -2.8062879629, -47.6728698649 -2.8062995965, -47.6728952856 -2.8063088527, -47.672897007 -2.8063093833, -47.672949984 -2.8063200428, -47.6729517767 -2.8063202193, -47.672966443 -2.8063209226, -47.6729679855 -2.8063213223, -47.6733393514 -2.8064196858, -47.6733738728 -2.8064264543, -47.6733761939 -2.8064267537, -47.6733804796 -2.8064270239, -47.6733890639 -2.806431641, -47.6734057692 -2.8064398944, -47.6734069006 -2.8064404055, -47.6734241363 -2.8064474849, -47.6736663052 -2.8065373005, -47.6736676833 -2.8065378073, -47.6736677752 -2.8065378409, -47.673669156 -2.8065383402, -47.6737754465 -2.8065764489, -47.673793217 -2.8065850801, -47.6737945765 -2.8065856723, -47.6738366895 -2.8066000123, -47.6738381279 -2.8066003728, -47.6738811819 -2.8066074503, -47.6739137725 -2.8066153813, -47.6739159177 -2.806615636, -47.6739318345 -2.8066165588, -47.673951326 -2.806622013, -47.6739530661 -2.8066223195, -47.6739793945 -2.8066256302, -47.6740948445 -2.8066344025, -47.674240062208945 -2.8066454423517624))');
INSERT INTO TEMP_TEST_GEOMETRY
VALUES (SDO_CS.TRANSFORM (SDO_GEOMETRY (str, 4674), 1000205));
dbms_lob.freetemporary(str);
end;
/
You can make the chunks smaller and have many more appends, which may be more manageable in some respects, but is more work to set up. It's still painful to do manually though, so this is probably a last resort if you can't get the value some other way.
If the string is coming from an an HTTP call you can read the response in chunks and convert it into a CLOB as you read it in much the same way, using dbms_lob.append. Exactly how depends on the mechanism you're using to currently get the response. Also worth noting that Oracle 12c has built-in JSON handling; in earlier versions you may be able to use the third-party PL/JSON module, which seems to handle CLOBs.

Related

How to extract EXIF metadata from BLOB column

I am trying to extract geolocation from EXIF metadata and the JPEG-image is stored in blob column in Oracle Database 12c using PLSQL.
Oracle Multimedia package is installed. The image contains data about geolocation before uploading, and when I download it again from the BLOB, latitude and longitude are there in metadata. But when I try to read it in database, I can read only basic metadata like image width, height, size, mimetype.
I am using this procedure to extract metadata from BLOB column:
PROCEDURE extractMetadata(inID IN INTEGER) IS
img ORDSYS.ORDIMAGE;
metav XMLSequenceType;
meta_root VARCHAR2(40);
xmlORD XMLType;
xmlXMP XMLType;
xmlEXIF XMLType;
xmlIPTC XMLType;
BEGIN
-- select the image
SELECT ordsys.ordimage(d.blob,1)
INTO img
FROM PHOTOS d
WHERE d.id = inID;
-- extract all the metadata
metav := img.getMetadata( 'ALL' );
-- process the result array to discover what types of metadata were returned
FOR i IN 1..metav.count() LOOP
meta_root := metav(i).getRootElement();
DBMS_OUTPUT.PUT_LINE(meta_root);
CASE meta_root
WHEN 'ordImageAttributes' THEN xmlORD := metav(i);
WHEN 'xmpMetadata' THEN xmlXMP := metav(i);
WHEN 'iptcMetadata' THEN xmlIPTC := metav(i);
WHEN 'exifMetadata' THEN xmlEXIF := metav(i);
ELSE NULL;
END CASE;
END LOOP;
-- Update metadata columns
--
update photos SET metaORDImage = xmlORD,
metaEXIF = xmlEXIF,
metaIPTC = xmlIPTC,
metaXMP = xmlXMP
WHERE id = inID;
END extractMetadata;
but only metaORDImage is extracted.
It seems like there is no EXIF metadata available, but when I download image to my PC and check details, there is location data:
What could be wrong here? Is it possible at all to extract EXIF from BLOB and should I store the image in some other format rather than BLOB?
UPDATE: I used Javascript library exif-js to read metada on page when the image is loaded into webpage, and once again geolocation is there. I can read it anywhere but not in PLSQL.
{
"ImageWidth": 720,
"ImageHeight": 1520,
"ExifIFDPointer": 74,
"Orientation": 0,
"GPSInfoIFDPointer": 92,
"LightSource": "Unknown",
"GPSLatitude": [
43,
xx,
17.861
],
"GPSLatitudeRef": "N",
"GPSLongitudeRef": "E",
"GPSLongitude": [
17,
xx,
7.29
],
"thumbnail": {}
}
My proposal would be a Java class, e.g. Apache Commons Imaging or org.w3c.tools.jpeg or metadata-extractor
First you need to load the Java classes into your database. Can be done with the loadjava tool:
loadjava -verbose -user username/password#DATABASE_NAME -r -o .\commons-imaging-1.0-alpha3.jar
Then you need to define the PL/SQL procedure/function:
CREATE OR REPLACE FUNCTION getMetadata(img IN BLOB) RETURN VARCHAR2
AS LANGUAGE JAVA NAME 'Imaging.getMetadata(byte[] bytes) return java.lang.String';
/
In the final step you can use the PL/SQL as usual. Above function does not work, because of wrong return type but I hope you get an idea how it works in general.
See Calling Java Methods in Oracle Database and https://www.tabnine.com/code/java/classes/oracle.sql.BLOB

how the 'tmpdata' and 'Get_Parameter_List' works in OracleForm?

I am new in OracleForms and Plsql, i found this code in a proyect:
PROCEDURE grabar IS
...
Pl_id paramlist;
...
BEGIN
pl_id := Get_Parameter_List ('tmpdata');
IF NOT Id_Null(pl_id) THEN
Destroy_Parameter_List( pl_id );
END IF;
pl_id := Create_Parameter_List('tmpdata');
i want to konw that if 'tmpdata' does not exist i will get an error?
whit the line:
pl_id := Get_Parameter_List ('tmpdata');
am i inserting the data of 'tmpdata' in 'PL_id'
it is the 'tmpdata' a default variable of Oracleforms or something?
it is not OracleForms but it is a tool based in it so is so similar
I proved to change to:
pl_id := Get_Parameter_List ('tmpdata_HELLO');
enter code hereand the program passed to of this
the console show me this:
may 25, 2018 4:46:30 PM org.apache.tomcat.util.http.Parameters processParameters
INFORMACIÓN: Character decoding failed. Parameter [value] with value [%null] has been ignored. Note that the name and value quoted here may be corrupted due to the failed decoding. Use debug level logging to see the original, non-corrupted values.
Note: further occurrences of Parameter errors will be logged at DEBUG level.
In this example, "tmpdata" is the name of a parameter list that may or may not exist. The "ID_NULL" is checking for the existence of the parameter list by checking of the ID returned has a value or not. If it has a value (ie, ID_NULL returns FALSE), then the parameter list is destroyed so that the "Create_Parameter_List" command will not get an error.
"Get_Parameter_List" will not throw an error if there is no parameter list by the given name ("tmpdata", in this case); it just returns null.

SDO_UTIL.TO_GMLGEOMETRY throws srsname which starts with SDO: in stead of expected EPSG:

We have code which creates a wfs request in the program which is called to get some data from open data. In this code we use oracle procedure SDO_UTIL.TO_GMLGEOMTERY to complete request with necessary gml data.
used query is something like:
select
sdo_util.to_gmlgeometry(geom)
from geom_table;
Result should be something like:
<gml:Polygon srsName="EPSG:28992" xmlns:gml="http://www.opengis.net/gml">
<gml:outerBoundaryIs>
<gml:LinearRing>
<gml:coordinates decimal="." cs="," ts=" ">185610.0,320243.0 185620.0,320243.0 185620.0,320233.0 185610.0,320233.0 185610.0,320243.0 </gml:coordinates>
</gml:LinearRing>
</gml:outerBoundaryIs>
</gml:Polygon>
However, in some cases srsname in result is thrown as "SDO:28992" in stead of "EPSG:28992".
Does anyone know how to make sure srsname is returned as EPSG?

Sort column with text and number

I am trying to sort several csv files by the first column. Here is a an example of the output that I get:
OR7
OR8
OR10
OR100
OR101
OR102
OR103
OR104
OR105
OR106
OR107
OR109
OR11
OR111
OR113
OR114
OR115
OR117
OR119
Here is the command that I am using: sort -k 1.3,1.4n -k1.5n file (I am sorting by the first column)
However I would like to have it sorted like this:
OR7
OR8
OR10
OR11
OR100
OR101
OR102
OR103
OR104
OR105
OR106
OR107
OR109
OR111
OR113
OR114
OR115
OR117
OR119
I know that there are other similar questions here, but I could not figure out how to adapt their solution to my problem.
I am also using MacOS. I was just looking at an Ubuntu machine and the sort has more option (checking "man sort"). For example, when I try to use -V on my computer it does not work.
Thank you for your time.
Well I found a way around it in R. Since my goal was to make a Trellis plot. What I did was to set the column with the gene names as a factor and in the order I wanted. For example:
OR$Gene<-factor(OR$Gene, levels=(c("OR2", "OR3", "OR4", "OR5", "OR6", "OR7", "OR8", "OR10", "OR11", "OR12", "OR13", "OR14", "OR15", "OR16", "OR17", "OR18", "OR19", "OR20", "OR21", "OR23", "OR24", "OR25", "OR26", "OR27", "OR28", "OR30", "OR31", "OR33", "OR36", "OR39", "OR41", "OR42", "OR43", "OR44", "OR45", "OR47", "OR48", "OR49", "OR50", "OR52", "OR55", "OR56", "OR59", "OR62", "OR63", "OR66", "OR67", "OR69", "OR70", "OR71", "OR72", "OR76", "OR78", "OR79", "OR80", "OR81", "OR84", "OR85", "OR86", "OR87", "OR88", "OR91", "OR92", "OR93", "OR94", "OR95", "OR96", "OR97", "OR98", "OR100", "OR101", "OR102", "OR103", "OR104", "OR105", "OR106", "OR107", "OR109", "OR111", "OR113", "OR114", "OR115", "OR117", "OR119", "OR121", "OR122", "OR123", "OR124", "OR125", "OR126", "OR130"))
Then with the xyplot print command I used the index.cond:
index.cond = list(OR$Gene),
Well I got what I wanted, I am sure might be an easier way out there.
Best,

How in ColdFusion with in variables get a Oracle stored procedure to return values?

ORACLE 11g - COLDFUSION 9 - REF CURSOR - WITH at least one in variable.
How in ColdFusion with in variables get a Oracle stored procedure to return values?
We have tried several things, we can get a stored procedure to return a result set if we are not passing in variables but we cannot get them when we are passing in variables.
We know how to do it calling MS SQL.
Thanks for any help
P.S. we have heard this may not be possible with the current Oracle Driver is there a different Oracle driver?
From what I have been reading online I am thinking this is not just a coding issue. I hope I am wrong about that. This is just an example I was working on as a proof of concept so I can start creating all of them. I can get it work if I am not using a ref cusor.
Error Executing Database Query.
[Macromedia][Oracle JDBC Driver]The specified SQL type is not supported by this driver.
The error occurred in D:\apache\htdocs\test\index.cfm: line 86
84 :
85 :
86 :
87 :
88 :
CF Call to procedure
<cfstoredproc procedure="BWNGDBADEV.PACK_REFCURSOR.GETALL" datasource="mydatasourcename" returncode="no">
<cfprocparam type="InOut" cfsqltype="CF_SQL_INTEGER" variable="pPERSONNELID" value="4" null="No">
<cfprocparam type="Out" cfsqltype="CF_SQL_REFCURSOR" variable="AnyVarName">
<!--- *** This name ties StoredProc results to the query below *** --->
<cfprocresult name="myvar">
</cfstoredproc>
Oracle Package
CREATE OR REPLACE
PACKAGE PACK_REFCURSOR
AS
TYPE EMP_TableRows
IS
REF
CURSOR
RETURN BWNGDBADEV.PER_PERSONNEL%ROWTYPE;
PROCEDURE GETALL(
pPERSONNELID IN OUT BWNGDBADEV.PER_PERSONNEL.PERSONNELID%type,
OUTTABLE OUT EMP_TableRows);
END PACK_REFCURSOR ;
/
CREATE OR REPLACE
PACKAGE BODY PACK_REFCURSOR
AS
PROCEDURE GETALL(
pPERSONNELID IN OUT BWNGDBADEV.PER_PERSONNEL.PERSONNELID%type,
OUTTABLE OUT EMP_TableRows)
IS
BEGIN
-- implicit cursor is opened - no close needed ***
OPEN OUTTABLE FOR
SELECT *
FROM BWNGDBADEV.PER_PERSONNEL
WHERE PERSONNELID = pPERSONNELID;
END GETALL ;
END PACK_REFCURSOR ;
/
do you have the latest DataDirect JDBC drivers ?
v 3.5 drivers and release notes here: http://kb2.adobe.com/cps/000/42dcb10a.html
the release notes suggest it fixes your exact problem
There's a small note in the docs stating: "You cannot use the cfprocparam tag for Oracle 8 and 9 reference cursors. Instead, use the cfprocresult tag."
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7d52.html
Try something along these lines:
<cfstoredproc
procedure = "BWNGDBADEV.PACK_REFCURSOR.GETALL"
dataSource = "mydatasourcename"
returnCode = "Yes">
<!--- cfprocparam tags --->
<cfprocparam type="InOut" cfsqltype="CF_SQL_INTEGER" variable="pPERSONNELID" value="4" null="No">
<cfprocparam type="Out" cfsqltype="CF_SQL_REFCURSOR" variable="AnyVarName">
<!--- cfprocresult tags --->
<cfprocresult name="RS1" resultSet="1">
<cfprocresult name="RS2" resultSet="2">
</cfstoredproc>

Resources