Oracle unique index with condition - oracle

When I am learning oracle index, I encountered with the situation that I am not able to understand.
create unique index u_index1 on table_a(case when code is not null then company_id end, code)
I am not able to understand the purpose of this code, Does this index mean that, if code is not null then index on code, company_id is created? or if code is null then index is created on code column only? or what?

The meaning of this index(ultimately unique constraint) is:
When you insert NULL into code then uniqueness will be checked on (NULL, CODE). Ok but code is also NULL so index will be on (NULL, NULL). means on nothing.
When code is not null then index will be on (COMPANY_ID, CODE)
Now, let's take this in this way:
COMPANY_ID can have multiple duplicates with NULL CODE but for a single COMAPNY_ID, There must be a unique CODE
Cheers!!

Related

Oracle - Unique constraint while allowing null values

I'm a bit new to PL-SQL coming from T-SQL.
I have a requirement that only one phone number is allowed per user ID, but the phone number column can be null as many times as required.
So table is:
User ID
Phone Number
1
NULL
1
9735152122
1
NULL
2
NULL
3
NULL
1
2124821212
It's that last one I need to block, although the first three are fine. In this case I'm talking about the sample table I've posted, not the actual table order. I just need to allow the NULLs through but block if there are duplicate phone numbers per a given User ID.
I've read about functional indexes but not sure exactly how to apply them here.
CREATE UNIQUE INDEX my_index ON my_table (
CASE WHEN phone_number IS NULL THEN NULL ELSE user_id END,
phone_number
)
With this logic, if phone_number is NULL, then both values in the index will be NULL, so that row will be excluded from the index. If phone_number is not NULL, then the row will be included in the index with the actual values for user_id and phone_number, and uniqueness will be enforced.
P.S. This is not "PL/SQL", it is Oracle SQL. PL/SQL is the procedural language used to write such things as triggers, functions, etc.

how to get Null records from oracle database if column is Number type and nullable

I have Oracle database table with three columns i.e Id,RTOName,VehicleCode. my table looks like below
RTOName is the varchar2 type and VehicleCode is NUMBER(2,0) and is nullable field.
So I have the data like below and I want to fetch the records with Some VehicleCode and with null value. The table design like this already done so changing that will impact a lot in my application. I have a JPA Native Query that I used like this and I want to fetch the records with null values.
Query query = createNativeQuery("select RTOName,VehicleCode from tbl_vehiclecodes WHERE VehicleCode=#vCode");
query.setParameter("vCode", vehicleCode);
From above Query I will get only Non null valued record. Eg. for vCode parameter 61 I will get
Marathalli,61. If my vCode is null I have a problem and I wont get any record.
How to achieve this in Native Query?
I know that we can use IS NULL in the Query in where clause. Since I have some numbers here In my case how to solve this? Any help
Thanks
We can use OR here,
Following query will give you records with matched records for parameter vCode along with rows having null and in case of vCode is null you get the records only with null values.
Query query = createNativeQuery("select RTOName,VehicleCode from tbl_vehiclecodes WHERE (VehicleCode is null or VehicleCode=#vCode)");
Edit: considering the doubts from #Ranagal
If you want like in case of null value passed to vCode you want all the records having value in vehiclecode and also with null then we need to change the query like,
Query query = createNativeQuery("select RTOName,VehicleCode from tbl_vehiclecodes WHERE (VehicleCode is null or VehicleCode=coalesce(#vCode,VehicleCode))");

Which performes better for a function based index: NVL2 or DECODE?

I'd like to create a function based index in order to index NULL values in a column on an oracle 11g table.
Which performs better: NVL2 or DECODE?
NVL2(nr.processed_datetime,'Y','N')
or
DECODE(nr.processed_datetime,NULL,'N','Y')
To find a column value is null or not null you NO need to use any function.
in your SQL where condition use IS NULL or IS NOT NULL
Where nr.processed_datetime IS NULL ;
or
Where nr.processed_datetime IS NOT NULL;
for better performance, you can just crate normal index on that column that should be fine

UPDATE in procedure ORA-00001

I have w problem with UPDATE in procedure. Procedure compiling and I see(DBMS...) results example 100records and error
ORA-00001: unique constraint violated (CUSTOMER_INFO_COMM_METHOD_UX)
My update:
UPDATE customer_info_comm_method_tab SET Value=wynikOK WHERE
customer_id=cus_rec.customer_id AND method_id='E_MAIL' AND Value = p_stringWyn;
wynikOK - actual new Value
cus_rec.customer_id - actual customer_id from cursor
p_stringWyn - old Value in table
key is founded on three attributes that I use (CUSTOMER_ID, VALUE, METHOD_ID)
Of course I can't remove index CUSTOMER_INFO_COMM_METHOD_UX because Its not my database
If I commented update procedure compile 100% without error but I need to do this update
It means that your new value (wynikOK) is causing the violation. The combination of customer_id , your new value(wynikOK) and method id is already existing in another row of your table. But this has to be unique...
If this combination of values(customer,value,method) is not gonna be unique , then remove the unique constraint in the table..
Else value has to be unique. Try appending some strings for your new value so that it will be unique. Say if your value is 1234, try appending the date to this value 1234_23112012 so that this will be unique always.

Conditional unique constraint in oracle db

I have a situation where I need to enforce a unique constraint on a column[attribute] depending on another column value.
So for example, I have a table like Table(ID, EID, Name, ISDeleted)
ISDeleted can only have a value null or 'y' (active or deleted), and i want to create a unique constraint on EID, ISDeleted only when ISDeleted = null, since I dont care if there are multiple deleted records with the same id. Please note that, EID can have null value.
I am using Oracle DB for this.
You can't create a constraint. But you can create a unique function-based index. This takes advantage of the fact that Oracle does not index NULL values-- any rows where isDeleted is NOT NULL will not be included in the index so the unique constraint won't apply to them.
CREATE UNIQUE INDEX one_not_deleted
ON table_name( (CASE WHEN isDeleted IS NULL
THEN eid
ELSE null
END) );

Resources