Force decimal value, even when 0 in oracle - oracle

I have a field that stores version information such as 1.1, 1.2 etc. However, it will store 4.0 as 4 and 5.0 as 5.
Is there a way to force it to show the .0?
I have tried NUMBER(5, 3) and DECIMAL(5, 3) data types and neither work.
Version - Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production

A NUMBER column will never store the decimal value if it doesn't need to.
You can, however, control how the data is displayed to the user when it is converted to a string by using an explicit TO_CHAR rather than relying on implicit data type conversion. If you use the format mask 9.0 in your TO_CHAR call, for example, the string that is generated will always have 1 decimal digit.
SQL> select to_char( 4, '9.0' )
2 from dual;
TO_C
----
4.0
SQL> ed
Wrote file afiedt.buf
1 select to_char( 4.1, '9.0' )
2* from dual
SQL> /
TO_C
----
4.1
That being said, it seems unlikely that you would really want to store software version information in a NUMBER column rather than a VARCHAR2. You, presumably, aren't doing any mathematical operations on the data so most of the benefit of having a NUMBER is off the table. And software versions are not inherently numeric. You often find yourself wanting more than two components (i.e. Oracle 11.2.0.1). And software versions tend to have highly non-numeric things done to them. If the version that follows 4.9 is 4.10, that's very different than the version 4.1 that followed 4.0. If you're using a NUMBER, though, you lose the ability to differentiate between those versions.

If you need to hide this from your code, create a view to hide these details.
It will however, be a string for the same reason Justin indicates.

Related

SQL Developer doesn't display XML

Oracle's SQL Developer doesn't display the content of XML columns when the datatype XMLType is used. The first lines are displayed ok (if Preferences > Database > Advanced > Display XML Value in Grid is ticked), but once you doubleclick on the little yellow pencil, the "View Value" window remains empty. Curiously, it works if you store the XML in a clob.
CREATE TABLE t (x XMLTYPE, c CLOB);
INSERT INTO t VALUES (XMLTYPE('<x/>'), '<x/>');
COMMIT;
SELECT * FROM t;
After a lot of internet search, I found a post by thatJeffSmith saying that it's a known bug and will be fixed soon. And yes, it is working again from version 19.1 onwards. However, at work we are stuck with version 18.2 for a while. So, is there a workaround in 18?
Version XML View Value
17.3.0.271 ok
17.4.0.355 ok
18.1.0.095 empty
18.2.0.183 empty
19.1.0.094 ok
19.2.1.247 ok
19.4.0.354 ok (but needs modern JDK)
This is how it looks in 19.1:
Secondly, I couldn't find a list of bugs for SQL Developer, or a list of fixed bugs, or old release notes. Currently, Oracle's download page lists only the latest three releases 19.1, 19.2 and 19.4, so it's impossilbe to find out when this bug was fixed.
The proper solution is an upgrade to version 19 (or theoretically downgrade to 17).
If you are stuck in Version 18, there is a workaround:
SELECT t.x.getClobVal() FROM t t;
For some strange reason, the table alias is required.

Why Does Oracle 10g to_char(date time) Truncate Strings?

I got a bug report where Oracle 10g was truncating return values from to_char(datetime):
SQL> select to_char(systimestamp, '"day:"DD"hello"') from dual;
TO_CHAR(SYSTIMESTAMP,'"DAY:"DD"HE
---------------------------------
day:27hel
Notably, this does not appear to happen in Oracle 11g. My question is, why does it happen at all? Is there some configuration variable to set to tell to_char(datetime) to allocate a bigger buffer for its return value?
I'm not sure but it might be just displaying in SQL*Plus. Have you tried to run it in Toad? Or if you assign result to varchar2 in PL/SQL block and output result?
Here what I've found in SQL*Plus Reference for 10g:
The default width and format of unformatted DATE columns in SQL*Plus
is determined by the database NLS_DATE_FORMAT parameter. Otherwise,
the default format width is A9. See the FORMAT clause of the COLUMN
command for more information on formatting DATE columns.
Your values is trimmed to 9 characters which corresponds to default A9 format. I don't have same version and this behaviour is not reproducing in 11g so can you please check my theory?
I've got the same problem and I know the solution.
I use Release 11.2.0.4.0 but I beleave it is possible to repeat the situation in other versions. It somehow depends on client. (E.g. I cannot repeat it using SQL*Plus, only with PL/SQL Devepoper)
Try this:
select to_char(systimestamp, '"day:"DD"йцукенг OR any other UTF-encoded-something"') from dual
union all
select to_char(systimestamp, '"day:"DD"hello"') from dual;
You'll get the following result:
day:08йцукенг OR any other UTF-encoded-so
day:08hello
You can see the "mething" is lost. This is exactly 7 bytes exceeded because of 7 two-byte simbols "йцукенг". Oracle allocates buffer for the number of characters, not a number of required bytes.
The command
alter session set nls_length_semantics=byte/char
unfortunately does not affect this behavior.
So my solution is to cast a result as varchar2(enough_capacity)
select cast(to_char(systimestamp, '"day:"DD"йцукенг OR any other UTF-encoded-something"') as varchar(1000)) from dual
union all
select to_char(systimestamp, '"day:"DD"hello"') from dual
Explicit typecasting makes expression independent from client or configuration.
BTW, the same thing happens in all implicit to_char-conversions. E.g.
case [numeric_expression]
when 1 then '[unicode_containing_string]'
end
Result might be cutted.

Oracle Forms 10g - 'NULLS' is not accepted

Oracle Forms 10g - 'NULLS' is not accepted.
In program unit(PL/SQL Code) I use NULLS FIRST and its throwing error.
Encountered the symbol NULLS
select line_id
from oe_order_lines_all
where rownum <5
order by line_id NULLS FIRST;
kindly help
I am not familiar with forms, but a simple workaround (if it works) is to modify the order by clause. For example, assuming the line id's are positive, or at least non-negative, you could
order by nvl(line_id, -1)
The flavour of PL/SQL and SQL used in Forms is different and somewhat older than the one available in the database. Being able to run code on the database does not mean it will run without changes in Forms. Analytic functions is an example of a newer SQL feature which is missing in Forms. But you can always put your code into a PL/SQL package in the database and call it from your forms code.

Cannot store a large double into Oracle (ORA-01426: numeric overflow)

In my Oracle (Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production), this query fails:
select 9.1E+136 from dual;
It tells me something like: ORA-01426: numeric overflow (I've tried 9.1E136, 9E136 as well). Which is really strange, since numbers up to about 2E+308 should be supported (http://docs.oracle.com/javadb/10.10.1.2/ref/rrefsqljdoubleprecision.html).
I've bumped into this problem from an Hibernate application, which maps a double field to FLOAT with default precision of 126 (Should be more than enough (http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj27281.html).
Anyone any idea? Depends on some configuration parameter? Thank you in advance.
OK, I've found a solution: there is the binary_double type, numbers like that are cast to it when a d is appended to their value:
select 9.1E+136d from dual; # works
select 9.1E+136 from dual; # doesn't work
create table test ( no binary_double primary key );
insert into test values ( 9.2E136d ); # OK
insert into test values ( 9.3E136 ); # Fails
So needlessly stupid...
The Oracle documentation states that:
Positive numbers in the range 1 x 10-130 to 9.99...9 x 10125 with up to 38 significant digits
You are overflowing the number data type.
Numeric Types

Equivalent spatial types for insert statement

I have a number of files containing vast amounts of Insert statements (which were generated by Toad for Oracle) which I need to run on a Postgresql database.
Sounds simple I know but there are also oracle specific spatial data types in there which are hampering my efforts. I tried to use a number of tools for this from SwisSQL to SDO2Shp to migrate the data and none have been any help whatsoever so my only plan left to try is to come up with a C# program to open the file, replace the oracle specific types with types that will work in postgis and then save the file again. The problem is I have no idea which types I could substitute with the Oracle ones or the format or syntax I must use.
I am very new to postgresql and postgis and my oracle knowledge is also limited as I had previously used SQL Server.
Here is an example of the Insert statement. They will all have the same format as this as the tables are the same but with different data for different zoom levels on a map.
Insert into CLUSTER_1000M
(CLUSTER_ID, CELL_GEOM, CELL_CENTROID)
Values
(4410928,
"MDSYS"."SDO_GEOMETRY"(2003,81989,NULL,
"MDSYS"."SDO_ELEM_INFO_ARRAY"(1,1003,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
"MDSYS"."SDO_ORDINATE_ARRAY"(80000,106280,81000,107280,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)),
"MDSYS"."SDO_GEOMETRY"(2001,81989,
"MDSYS"."SDO_POINT_TYPE"(80500,106780,NULL),NULL,NULL));
How can I get this into a format that will work with postgis?
I have no idea on how the Oracle GIS implementation works:
But looking at the data, I don't think conversion will be possible (it might be, but the effort might be huge).
Look at the way PostGIS defines Geometry
INSERT INTO geotable ( the_geom, the_name )
VALUES ( ST_GeomFromText('POINT(-126.4 45.32)', 312), 'A Place');
PostGIS follows standards on how to display/store the data and offers methods do assist the developer to do so. This conversion is mostly with functions that have a *from* in their name. So to create the proper data from a line, the output is similar to aline
SELECT ST_LineFromWKB(ST_AsBinary(ST_GeomFromText('LINESTRING(1 2, 3 4)'))) AS aline,
ST_LineFromWKB(ST_AsBinary(ST_GeomFromText('POINT(1 2)'))) IS NULL AS null_return;
aline | null_return
------------------------------------------------
010200000002000000000000000000F ... | t
Judging from your example output from Oracle, the format is pretty different and might not be convertable (if Oracle isn't offerent something that is able to stick to the standard).
On the other hand, when looking at the Oracle example
INSERT INTO cola_markets VALUES(
1,
'cola_a',
SDO_GEOMETRY(
2003, -- two-dimensional polygon
NULL,
NULL,
SDO_ELEM_INFO_ARRAY(1,1003,3), -- one rectangle (1003 = exterior)
SDO_ORDINATE_ARRAY(1,1, 5,7) -- only 2 points needed to
-- define rectangle (lower left and upper right) with
-- Cartesian-coordinate data
)
);
you might be able to replace some of the Oracle names with the ones for PostGIS, so SDO_ORDINATE_ARRAY(1,1, 5,7) might turn into something like ST_GeomFromText(LINESTRING(1 1, 5 7))

Resources