Is Numeric in Oracle - oracle

I'm working in oracle 11g. I've a table with Number as the datatype. For development purpose we have created a staging table with varchar type. Initially data would be loaded in the staging table. We need find out the records that has only number in that column, since the data might contain the noises. Is there any way to find it.

You can select your data with a regexp_like :
SELECT *
FROM your_table t
WHERE REGEXP_LIKE (t.your_colonne, '^[0-9]+$');

The regexp_like function can be used to determine if a value consists of only digits. Here is an example:
with Your_table(your_column) as(
select '123456' from dual union all
select 'a123452' from dual union all
select '01456' from dual union all
select '1j6-d' from dual
)
select your_column
from your_table
where regexp_like(your_column, '^[[:digit:]]+$')
Result:
YOUR_COLUMN
--------------
123456
01456
SQL Fiddle Demo

Related

Inserting from a SELECT but changing one column in the middle?

Wondering if there is a way to insert a row into a table from another, with exception of one column in the middle without specifying all the column name? I have 128 columns in the table.
I created a view to store the original records.
CREATE VIEW V_TXN_STG AS
SELECT * FROM TXN_STG;
In table TXN_STG, only one column BRN_CODE is changing.
Something like this doesn't work, because the column is not on the last, but somewhere middle of table structure.
INSERT INTO TXN_STG
SELECT v.*, 'BRN-001' AS BRN_CODE
FROM V_TXN_STG v;
I don't believe that this is possible without explicitly specifying the columns in your select.
first you have to get the columns:
SELECT listagg(column_name, ',') within group (order by column_name) columns
FROM all_tab_columns
WHERE table_name = 'AAA' --Table to insert too
and column_name <> 'B' -- column name you want to exclude
GROUP BY table_name;
Then insert that result on the first row:
insert into aaa(A,C) -- A,C is my result from above,I have excluded column B
select *
from (select 'a' A,'q' AMOUNT,'c' C from dual union all -- my sample data
select 'a','a','c' from dual union all
select 'a','b','c' from dual union all
select 'a','c','c' from dual union all
select 'a','d','c' from dual )
pivot
(
max(1)
for (AMOUNT) -- the column you want to remove from the sample data
IN ()
)
where 1=1
order by A;

PL/SQL FOR Loop Error when Populating Dimension Table

I am populating a dimension table named TIMES with data from an OLTP Table called SALES with the following code:
CREATE TABLE TIMES
(saleDay DATE PRIMARY KEY,
dayType VARCHAR(50) NOT NULL);
BEGIN
FOR rec IN
(SELECT saleDate, CASE WHEN h.hd IS NOT NULL THEN 'Holiday'
WHEN to_char(saleDate, 'd') IN (1,7) THEN 'Weekend'
ELSE 'Weekday' END dayType
FROM SALES s LEFT JOIN
(SELECT '01.01' hd FROM DUAL UNION ALL
SELECT '15.01' FROM DUAL UNION ALL
SELECT '19.01' FROM DUAL UNION ALL
SELECT '28.05' FROM DUAL UNION ALL
SELECT '04.07' FROM DUAL UNION ALL
SELECT '08.10' FROM DUAL UNION ALL
SELECT '11.11' FROM DUAL UNION ALL
SELECT '22.11' FROM DUAL UNION ALL
SELECT '25.12' FROM DUAL) h
ON h.hd = TO_CHAR(s.saleDate, 'dd.mm'))
LOOP
INSERT INTO TIMES VALUES rec;
END LOOP;
END;
/
When I run this, I'm getting the errors ORA-00001 (Unique Constraint Violation) and ORA-06512. I believe this is happening because the code is trying to input multiple dates (some of which are the same) into PK for my TIMES Dimension Table (saleDay). How would I implement a clause into this loop so it will only populate one instance of each saleDate into the saleDay PK so there isn't a violation?
For instance, If there are three rows in the SALES table where the saleDate is 2015-10-10, the code should only populate ONE instance of 2015-10-10 into the saleDay PK. I'm thinking the direction I should head is to implement a WHILE clause, however I'm not 100% sure on how that would work since this code is also using CASE to determine whether the saleDay was a Holiday, Weekday, or Weekend and populating the result into the dayType column.
Adding DISTINCT as suggested in a Comment below your question is one way to solve the problem.
The following approach may be more efficient:
for rec in (select distinct saledate from sales)
loop
insert into times (saleday, daytype) values
(rec.saledate, CASE .......);
end loop;
That is: put the CASE expression in the INSERT statement, not in the definition of the (implicit) cursor. There is no reason to compute the CASE expression multiple times for the same date, which may appear many times in the SALES table. There is no reason for the CASE expression to be part of the cursor, either. The CASE expression can use an IN condition (case when to_char(rec.saledate, 'dd.mm') in ('01.01', '15.01', ....) then 'Holiday' when .......)
Unless, of course, the homework problem specifically instructs you to use a left outer join....... :-(
Adding DISTINCT resolved this. Originally thought DISTINCT would negatively impact the CASE but it doesn't. Thanks to I3rutt for pointing this out.
BEGIN
FOR rec IN
(SELECT DISTINCT saleDate, CASE WHEN h.hd IS NOT NULL THEN 'Holiday'
WHEN to_char(saleDate, 'd') IN (1,7) THEN 'Weekend'
ELSE 'Weekday' END dayType
FROM SALES s LEFT JOIN
(SELECT '01.01' hd FROM DUAL UNION ALL
SELECT '15.01' FROM DUAL UNION ALL
SELECT '19.01' FROM DUAL UNION ALL
SELECT '28.05' FROM DUAL UNION ALL
SELECT '04.07' FROM DUAL UNION ALL
SELECT '08.10' FROM DUAL UNION ALL
SELECT '11.11' FROM DUAL UNION ALL
SELECT '22.11' FROM DUAL UNION ALL
SELECT '25.12' FROM DUAL) h
ON h.hd = TO_CHAR(s.saleDate, 'dd.mm'))
LOOP
INSERT INTO TIMES VALUES rec;
END LOOP;
END;
/

how to display identical values in a single column using EXCEL or ORACLE

Hello I need a formula in column ā€˜Cā€™ which calculates/adds the amount of B Column based on the column A ID. If there are several amounts in same ID it should add the total amount and would show the result in column ā€˜Cā€™ as a single row.
the output can be obtained from Oracle SQL query or an Excel formula.your help would be appreciated.
You can get the same output from Oracle itself, using analytical functions like below.
SUM() OVER(PARTITION BY ... ) -> This actually do the cumulative sum
WITH MYTABLE(ID,AMT) AS
(SELECT '2UF2', '500' FROM DUAL
UNION ALL
SELECT '2TC6', '300' FROM DUAL
UNION ALL
SELECT '2TC6', '200' FROM DUAL
UNION ALL
SELECT '2TC6', '800' FROM DUAL
)
SELECT ID,
AMT,
CASE ROW_NUMBER() OVER(PARTITION BY ID ORDER BY NULL)
WHEN 1
THEN SUM(AMT) OVER(PARTITION BY ID ORDER BY NULL)
END AS FORMULA
FROM MYTABLE
ORDER BY ID, FORMULA NULLS LAST;
SQL Fiddle Demo
You can use rollup in oracle
Select id,amt,sum (amt) nullFrom table nullGroup by rollup (id,amt)
For more details see below link
https://oracle-base.com/articles/misc/rollup-cube-grouping-functions-and-grouping-sets
In SQL you need an aggregation function, in this case sum, and a group by clause. The generic query should look like the following:
Select sum(b) from table group by a
I hope this helps.

Short test statements in PL-SQL?

In SQL server I can print out the value of something with a select statement.
SELECT 'xyz'
SELECT GetDate()
Can I do something similar in Oracle without adding FROM <tablename>?
This is the purpose of the dual table. Oracle supplies the Dual in every database and it's accessible, by default, to everyone that connects. It's a single-row, single column table that is useful for testing expressions and pseuducolumns against. Example
SELECT 'xyz' from dual;
SQL> select user,sysdate,lower(user) loweruser, 10*1023 from dual;
USER SYSDATE LOWERUSER 10*1023
---------- ---------- ---------- ----------
NKODNER 22-NOV-11 nkodner 10230
There is a dual dummy table in Oracle, so try:
SELECT GetDate() FROM dual
You can't. You must use DUAL fictious table
To get current system date, you would type
SELECT SYSDATE FROM DUAL

generate Multiple UUID Oracle

Oracle:-
I have around 850 records in an table, that need to be assigned UUID.
I am using the following query.
select substr(sys_guid(),1,3)||'-'||
substr(sys_guid(),4,4)||'-'||
substr(sys_guid(),8,4)||'-'||
substr(sys_guid(),13)
from (select sys_guid() as mygid from dual)
I need to generate multiple/850 records in one go.
Any suggestions ?
Should I loop over?
If you really need select, use hierarchical query:
SELECT Substr(mygid,1,3)||'-'||
Substr(mygid,4,4)||'-'||
Substr(mygid,8,4)||'-'||
Substr(mygid,12)
FROM (
SELECT Sys_GUID() AS mygid FROM dual
CONNECT BY Level <= :desired_number_of_records
)
But what's wrong with usual update ?
UPDATE your_tab
SET gid_col = (
SELECT Substr(mygid,1,3)||'-'||
Substr(mygid,4,4)||'-'||
Substr(mygid,8,4)||'-'||
Substr(mygid,12)
FROM( SELECT Sys_Guid() AS mygid FROM dual )
)
Not sure that format is really what you want as you are missing 9 of the 32 characters, buy you could modify the format as needed. Here is an example that shows how to format like XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX:
UPDATE MY_TABLE
SET GUID_COL = (
select regexp_replace((rawtohex(sys_guid()), '([A-F0-9]{8})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{4})([A-F0-9]{12})', '\1-\2-\3-\4-\5') as FORMATTED_GUID from dual
)

Resources