decimal data type in Oracle - sql

My database table contains one column of varchar2(20,10), but since it is a total amount field I need currency data type. (If I enter 1235.5 it should take it as 1235.50.)
I tried changing to type number(20,2), I am not able to do this with number(20,2) in Oracle 10g.

I guess you need not bother about insert, as long you have a precision of atleast 2. When you are fetching using select query, try using the select query as :
Select to_char(1234.4, 'fm9999999.00') from dual;
Select to_char(1234.45, 'fm9999999.00') from dual;
Select to_char(1234,'fm9999999.00') from dual;
Select to_char(1234.4567, 'fm9999999.00') from dual;

Related

Truncate not workng in MySQL

I guess the correct way of truncating a value in MySQL is truncate(value,limit); but that doesn't seem to be working here it needs an extra table name;
select truncate(94204.27348,2);
ERROR at line1:
ORA-00923: FROM keyword not found where expected
Assuming you are using Oracle, you must supply a table reference on your select query.
Oracle select queries require a table reference always.
You can do this....
Select truncate(94204.27348,2) -- see further comment below
From dual
;
Dual is a special table that allows these sort of queries.
Also, I think you might mean to use the TRUNC function.
As others have pointed out, the TRUNCATE query is not quite the same, it will erase the contents of the table that you supply it.
In Mysql You should use round. Truncating table will remove the data from the table and reset all your auto increment values.
SELECT ROUND(94204.27348,2);
Result - 94204.27
This will round the value and display only two decimal places.

Select from nothing in Oracle without referencing the dual table?

selecting from nothing in Oracle SQL happens while referencing the dual table, like
SELECT sysdate FROM dual;
Now I'd like to have a query that also works for PostgreSQL, but selecting from dual there isn't possible. I know that I can drop the whole FROM part, but then it won't work in Oracle.
I've also tried things like SELECT CURRENT_TIMESTAMP FROM VALUES(1)) V(C);, but Oracle can't do this, either.
So is there a way to select from nowhere without using the dual table in Oracle SQL?
Alternatively, create a table named dual in Postgres, made of 1 row and 1 column
create table dual as (select 1);
and you can use it in Postgres as you would in Oracle
select 'whatever' from dual;
?column?
-----------
whatever
sysdate in Oracle is a built-in function, i.e. not a database table column. You can use any table as long as the query returns precisely one row, e.g.
select sysdate from EMP where rownum < 2
If you have a small table, TABLE_B, with at least one row, you could try selecting a single row from it.
select sysdate from TABLE_B where rownum < 2;
The contents of the table don't matter because you won't be selecting any of its columns.
The below code generates a fake row in both Oracle and Postgres (10+), using the XMLTABLE function. This code is pretty weird but it doesn't require any custom objects.
--Generate a fake row in either Oracle or Postgres.
select *
from xmltable
(
--The expression syntax is different for Oracle and Postgres.
--Oracle can use a literal, Postgres must reference the XML.
--The string '' is null in Oracle but not null in Postgres.
case when '' is null then '1' else '/a' end passing '<a>1</a>'
columns test int path '.'
);
test
----
1

SQL secondary headers within data

I am having an issue that I haven't found an answer to. I wrote an SQL Query to generate a report that runs fine and outputs mostly numeric fields. The issue I'm running into is that we are putting it into a program that emails out files and it can only email out a .csv that does not include the header rows.
Is there a way to input the headers into the data? I've found a few solutions on here that didn't work for me. It seems like no matter what I do I get a data type error. This is all on an Oracle Database, the program we are using to send data out is called IQAlert, it's part of IQMS which is a manufacturing/erp system.
So far I've tried casting the headers as a number of numerical fields, a number of other solutions I found on here and other places on the internet such as changing to titles to varchar. The error I'm currently getting is
"ORA-01790: expression must have the same datatype as corresponding
expression"
Here is an extremely parsed down sample of the code. Adding the title "itemno' works fine because that field is text, when I try to add the header to onhand I get the data type error referenced above.
select 'itemno' as itemno, 'OnHand' as OnHand
from iqms.arinvt
union
select arinvt.itemno, arinvt.onhand
from iqms.arinvt
where itemno='10-00000000'
According to the documentation regarding The UNION [ALL], INTERSECT, MINUS Operators
You can combine multiple queries using the set operators UNION, UNION
ALL, INTERSECT, and MINUS. All set operators have equal precedence. If
a SQL statement contains multiple set operators, then Oracle Database
evaluates them from the left to right unless parentheses explicitly
specify another order.
The corresponding expressions in the select lists of the component
queries of a compound query must match in number and must be in the
same data type group (such as numeric or character).
If component queries select character data, then the data type of the
return values are determined as follows:
If both queries select values of data type CHAR of equal length, then
the returned values have data type CHAR of that length. If the queries
select values of CHAR with different lengths, then the returned value
is VARCHAR2 with the length of the larger CHAR value.
If either or both of the queries select values of data type VARCHAR2,
then the returned values have data type VARCHAR2.
If component queries select numeric data, then the data type of the
return values is determined by numeric precedence:
If any query selects values of type BINARY_DOUBLE, then the returned
values have data type BINARY_DOUBLE.
If no query selects values of type BINARY_DOUBLE but any query selects
values of type BINARY_FLOAT, then the returned values have data type
BINARY_FLOAT.
If all queries select values of type NUMBER, then the returned values
have data type NUMBER.
In queries using set operators, Oracle does not perform implicit
conversion across data type groups. Therefore, if the corresponding
expressions of component queries resolve to both character data and
numeric data, Oracle returns an error.
In short: in a query using one of the SET operators, for example like this:
SELECT x FROM table
UNION
SELECT y FROM table
where x is of numeric datatype, and yis of character datatype (or vice versa), then Oracle does not perform implicit conversion across data type groups and returns an error
Two simple examples:
SELECT 1 as X FROM dual
UNION
SELECT 'John' as Y FROM dual
ORA-01790: expression must have same datatype as corresponding expression
SELECT 'John' as X FROM dual
UNION ALL
SELECT 123 as Y FROM dual;
ORA-01790: expression must have same datatype as corresponding expression
Because Oracle does not perform implicit conversion, you must do an explicit conversion of one datatype to another datatype, the easiest one is to convert numbers to strings using TO_CHAR conversion function, like in this example:
SELECT 'John' as X FROM dual
UNION ALL
SELECT to_char(123) as Y FROM dual;
X
----
John
123
Maybe this will help. The first number is just sequence, the ROWNUM or ROW_NUMBER() can be used instead. The rest of numbers is simulated values:
SELECT itemno, onhand FROM
(
select 1 row_seq, NULL itemno, to_number(null) onhand from dual
union all
select 2, '5', 6 from dual
union all
select 3, '7', 8 from dual
)
WHERE row_seq > 1
/
Output:
ITEMNO ONHAND
5 6
7 8

Fetch multi output from SQL Transformation at Informatica

I want to fetch query result from informatica SQL Transformation.
I get a sql query to an input port(QUERY) also want to fetch sysdate
SELECT (~QUERY~),SYSDATE FROM DUAL;
But it does not let me to fetch such a result as 2 output column.
When I write
~QUERY~
it is giving me result, but I need 2nd or 3rd column.
Thanks
Ok, first try putting sysdate into the query as one of the columns rather than encapsulating and selecting from dual
e.g. SELECT A.COLUMN, A.COLUMN2, SYSDATE, A.COLUMN3 FROM TABLENAME A WHERE CONDITION
Then if you want a multi row return you can use an inline lookup configured to return multiple rows (cant select from dual in a lookup). The one gotcha is that you must be on powercenter 9.1 or higher... otherwise you'll need to put that query in a source qualifier and use a joiner to bring it into the main pipeline. Why sysdate from the database rather than the native informatica SYSTIMESTAMP function?
My code was working with 9.5.1, have problem with 9.6.1
SELECT (~QUERY~),SYSDATE FROM DUAL;
You can put as statement to assign column to output port. Assume that outport port is RESULT and DATETIME
SELECT (~QUERY~) RESULT ,SYSDATE DATETIME FROM DUAL;

ORA-01843: not a valid month error

I have a column in Oracle DB which is varchar2 data type. Typical value stored in this column is like 06/16/2015 02:14:18 AM.
I am trying to get all records wherein this column is having records after 1st August 2015.
select *
from MYTABLE
where to_date(substr(MYCOLUMN,1,10),'dd-mm-yyyy') > to_date('01-08-2015','dd-mm-yyyy');
But, I am getting ORA-01843. Where am I doing wrong?
Respect the format in your VARCHAR
....where to_date(substr(MYCOLUMN,1,10),'mm/dd/yyyy')
I have a column in Oracle DB which is varchar2 data type. Typical value stored in this column is like 06/16/2015 02:14:18 AM.
The first question is why do you store DATE as string? Using appropriate data type is one of the most important part of database design and performance.
Understand that DATE doesn't have the format you see, it is internally stored in 7 bytes which is Oracle's proprietary format. Storing date as a string to have a fixed format is not recommended.
I would suggest first fix the design so that you don't have to do this overhead activity while comparing dates. In the longer run it will help you.
1. Add a new column as DATE data type.
ALTER TABLE table_name
ADD new_column DATE;
2. Update the new column.
UPDATE table_name
SET new_column = TO_DATE(old_column, 'mm/dd/yyyy hh:mi:ss pm');
3. DROP the old column.
ALTER TABLE table_name
DROP COLUMN old_column;
4. Rename the new column to old column name.
ALTER TABLE table_name
RENAME COLUMN old_name to new_name;
Now, you could compare dates easily:
SELECT * FROM MYTABLE WHERE mycolumn > to_date('01-08-2015','dd-mm-yyyy');
This will also use any regular index on the date column.
From performance point of view:
If you don't fix it now, you will keep facing performance issues. Because the immediate fix of SUBSTR will not let you use any regular index, you need to create a function-based index.
If in your table all values like 06/16/2015 02:14:18 AM then you can use trunc(to_date(MYCOLUMN,'mm/dd/yyyy HH:mi:SS PM'),'dd') against to_date(substr(MYCOLUMN,1,10),'dd-mm-yyyy').