How to validate nulls - oracle etl testing? - oracle

I am new to oracle and I would like to know how do we check the nulls in non null columns in oracle tables as part of the ETL testing process. (The two tables could be T1 and T2). Please let me know a sample query.
I have already tried
select count(*) from T2 where T2.column is Null;
Thanks, Santosh

'=' operator can not be used while comparing to null. Replace '=' to 'is' as per below query.
select count(*) from T2 where T2.column is Null;

Assume there is column name: id in the table record, and id should not contain any null value. Query to check this is:
select id from record where id is null;

Related

How to copy all constrains and data form one schema to another in oracle

I am using Toad for oracle 12c. I need to copy a table and data (40M) from one shcema to another (prod to test). However there is an unique key(not the PK for this table) called record_Id col which has something data like this 3.000*******19E15. About 2M rows has same numbers(I believe its because very large number) which are unique in prod. When I try to copy it violets the unique key of that col. I am using toad "export data to another schema" function to copy the data.
when I execute query in prod
select count(*) from table_name
OR
select count(distinct(record_id) from table_name
Both query gives the exact same numbers of data.
I don't have DBA permission. How do I copy all data without violating unique key of the table.
Thanks in advance!
You can use UPSERT for decisional INSERT or UPDATE or you may write small procedure for this.
you may consider to use NOT EXISTS, but your data is big and it might not be resource efficient.
insert into prod_tab
select * from other_tab t1 where NOT exists (
select 1 from prod_tab t2 where t1.id = t2.id
);
In Oracle you can use a MERGE query for that.
The following query proceeds as follows for each data row :
if the source record_id does not yet exist in the target table, a new record is inserted
else, the existing record is updated with source values
For the sake of the example, I assumed that there are two other columns in the table : column1 and column2.
MERGE INTO target_table t1
USING (SELECT * from source_table t2)
ON (t1.record_id = t2.record_id)
WHEN MATCHED THEN UPDATE SET
t1.column1 = t2.column1,
t1.column2 = t2.column2
WHEN NOT MATCHED THEN INSERT
(record_id, column1, column2) VALUES (t2.record_id, t2.column1, t2.column2)

PL/SQL create function with param for a check constraint

Given the syntax:
CREATE [OR REPLACE] FUNCTION [Owner.]FunctionName
[(arguments [IN|OUT|IN OUT][NOCOPY] DataType [DEFAULT expr][,...])]
RETURN DataType [InvokerRightsClause] [DETERMINISTIC]
{IS|AS}
I think my query is syntactically correct, but for some reason, I get these errors during compilation:
Error(6,5): PL/SQL: SQL Statement ignored
Error(8,34): PL/SQL: ORA-00942: table or view does not exist
CREATE or replace FUNCTION aCombinationMismatches(p_column1 IN VARCHAR2)
RETURN Number
IS
duplicate_count NUMBER(4,0);
BEGIN
select count(*) into duplicate_count
from schema1.tableA a
inner join schema1.tableB b
on a.b_id = b.id and a.column1 = p_column1
group by a.b_id, a.column1, a.column2, b.column1, b.column2, b.column3;
return duplicate_count;
END;
Anyone see anything wrong with my query above?
Also I'd like to how to set this UDF up to be used to create a CHECK constraint. How exactly do I specify the param: p_param1 to the function assuming this is the value of a field column1 in a row that a user is trying to insert? I just don't want the user to insert a record into tableA that consists of duplicate combinations of fields across tables: tableA and tableB.
Note: The tables tableA and tableB do exist - a select query like below indicates it. So the error above is rather confusing to me, I must add. (All table and column names in the two queries were found/replaced with dummy values.)
select count(*)
from schema1.tableA a
inner join schema1.tableB b
on a.b_id = b.id
group by a.b_id, a.column1, a.column2, b.column1, b.column2, b.column3;
Output:
Count(*)
OK, you already know that you have problem with priviliges. I wanted to add that you won't be able to create CHECK constraint basing on your function. According to documentation:
The condition of a check constraint can refer to any column in the table, but it cannot refer to columns of other tables.
Conditions of check constraints cannot contain the following constructs:
Subqueries and scalar subquery expressions
Calls to the functions that are not deterministic (CURRENT_DATE, CURRENT_TIMESTAMP, DBTIMEZONE, LOCALTIMESTAMP, SESSIONTIMEZONE, SYSDATE, SYSTIMESTAMP, UID, USER, and USERENV)
Calls to user-defined functions
So to achieve what you want, you would have to define some triggers, or make use of some combination of MATERIALIZED VIEW and CHECK constraint. See for example this discussion on Ask Tom
You probably have access to TableA and TableB through a Role. This means that you can query the table, but you cannot create a procedure that reads or writes that table. In order to compile your procedure you should at least grant select on the table to your user.
In the link below you'll find more info
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1065832643319

How to create a blank/empty column with SELECT query in oracle?

I want to generate an output with blank/empty column with a "Select" query in oracle. I'm able to achieve this with below sql query:
SELECT CustomerName AS Customer, "" AS Contact
FROM Customers;
So when I run above sql query it returns a table with two columns "Customer" column with content in it and "Contact" column with no content or blank column.
I want to achieve same with oracle query. Any help will be highly appreciated.
I think you should use null
SELECT CustomerName AS Customer, null AS Contact
FROM Customers;
And Remember that Oracle
treats a character value with a length of zero as null.
In DB2, using single quotes instead of your double quotes will work. So that could translate the same in Oracle..
SELECT CustomerName AS Customer, '' AS Contact
FROM Customers;
I guess you will get ORA-01741: illegal zero-length identifier if you use the following
SELECT "" AS Contact FROM Customers;
And if you use the following 2 statements, you will be getting the same null value populated in the column.
SELECT '' AS Contact FROM Customers; OR SELECT null AS Contact FROM Customers;

Query using xquery and SQL on an sql table

I have an sql table with 3 columns and one of the columns is xml. Some of the elements in the xml are duplicates.
How do I query the table where the xml elements occur more than once??
Any help is appreciated. Thanks.
In the case of:
your table has a primary key (id here in sample)
your xml data are generated by program (so no tab, space, carriage return inserted by human)
I think, you can try to use the following query to find duplicate :
SELECT *
FROM <table> AS t1
WHERE EXISTS (SELECT 1
FROM <table> AS t2
WHERE t2.Id <> t1.Id
AND CONVERT(NVARCHAR(MAX),t2.<xmlcol>) = CONVERT(NVARCHAR(MAX),t1.<xmlcol>))

Column name is masked in oracle indexes

I have a table in oracle db which has a unique index composed of two columns (id and valid_from). The column valid_from is of type timestamps with time zone.
When I query the SYS.USER_IND_COLUMNS to see which columns my table is using as unique index, I can not see the name of the valid_from column but instead I see smth like SYS_NC00027$.
Is there any possibility that I can display the name valid_from rather than SYS_NC00027$. ?
Apparently Oracle creates a function based index for timestamp with time zone columns.
The definition of them can be found in the view ALL_IND_EXPRESSIONS
Something like this should get you started:
select ic.index_name,
ic.column_name,
ie.column_expression
from all_ind_columns ic
left join all_ind_expressions ie
on ie.index_owner = ic.index_owner
and ie.index_name = ic.index_name
and ie.column_position = ic.column_position
where ic.table_name = 'FOO';
Unfortunately column_expression is a (deprecated) LONG column and cannot easily be used in a coalesce() or nvl() function.
Use the below to verify the col info.
select column_name,virtual_column,hidden_column,data_default from user_tab_cols where table_name='EMP';

Resources