Oracle - Preventing duplicates based on two columns [duplicate] - oracle

This question already has answers here:
How to give a unique constraint to a combination of columns in Oracle?
(3 answers)
Closed 6 years ago.
Say that I have a table an Oracle 11g database that was defined like this
CREATE TABLE LAKES.DEPARTMENTAL_READINGS
(
ID NUMBER NOT NULL,
DEPT_ID INTEGER NOT NULL,
READING_DATE DATE NOT NULL,
VALUE NUMBER(22,1)
):
And the data in the table looks like this:
ID (PK) DEPT_ID CREATION_DATE VALUE
-------------------------------------------------------------
1 101 10/12/2016 3.0
2 102 10/12/2016 2.5
3 103 10/12/2016 3.3
4 101 10/13/2016 3.4
5 102 10/13/2016 2.7
6 103 10/13/2016 4.0
As you can see, I have one entry for each date for each department ID. There should no more than one. We have merge statements handling our scripts for data imports so most of this is being prevented when data is pulled in. However, as there's no telling who may continue to write scripts for this application and we want to be as stringent as possible. Is there a way to set constraints to prevent duplicate data from being entered for each dept_id/creation_date combination?

You can create composite primary key on those 2 columns together. This will deny insert by throwing an error.

Related

How to display page wise records in Oracle Database? [duplicate]

This question already has answers here:
How do I limit the number of rows returned by an Oracle query after ordering?
(14 answers)
Paging with Oracle
(7 answers)
Closed 7 months ago.
I have one table with name emp with columns id, name, address. I want SELECT records first 10 and then next 10 and so on depends on the variable. Please let me know how can I achieve this?
You can use below SELECT statement:
SELECT * FROM EMP where rownum between 1 and 10;
You can use 1 and 10 as two variables and replace it dynamically.

Get the last inserted row ID in trafodion

I want to get the row ID or record ID for last inserted record in the table in Trafodion.
Example:
1 | John <br/>
2 | Michael
When executing an INSERT statement, I want to return the created ID, means 3.
Could anyone tell me how to do that using trafodion or is it not possible ?
Are you using a sequence generator to generate unique ids for this table? Something like this:
create table idcol (a largeint generated always as identity not null,
b int,
primary key(a desc));
Either way, with or without sequence generator, you could get the highest key with this statement:
select max(a) from idcol;
The problem is that this statement could be very inefficient. Trafodion has a built-in optimization to read the min of a key column, but it doesn't use the same optimization for the max value, because HBase didn't have a reverse scan until recently. We should make use of the reverse scan, please feel free to file a JIRA. To make this more efficient with the current code, I added a DESC to the primary key declaration. With a descending key, getting the max key will be very fast:
explain select max(a) from idcol;
However, having the data grow from higher to lower values might cause issues in HBase, I'm not sure whether this is a problem or not.
Here is yet another solution: Use the Trafodion feature that allows you to select the inserted data, showing you the inserted values right away:
select * from (insert into idcol(b) values (11),(12),(13)) t(a,b);
A B
-------------------- -----------
1 11
2 12
3 13
--- 3 row(s) selected.

Vertica Primary Key Strange behavior [duplicate]

This question already has an answer here:
Unique Contrains in Vertica DB
(1 answer)
Closed 7 years ago.
I wrote this simple piece of code in vertica 7.1.2
select reenable_duplicate_key_error();
create table Person(id int PRIMARY KEY, firstname varchar(20));
insert into Person select 1, 'test1' union all select 1, 'test2' union all select 1, 'test3';
Now if I do a
select * from Person;
i see
id | firstname
----+-----------
1 | test1
1 | test2
1 | test3
(3 rows)
so it seems there is no effect of marking a key as primary key
This is expected and documented behavior. Vertica does not enforce uniqueness on load (imagine trying to ingest 500GB and having to rollback due to a PK violation). You can use analyze_constraints before committing or upgrade to 7.2 where you can enable enforcement of PK. It is still important to use keys for referential integrity.
See my blog post on other ways to enforce uniqueness on load.
Update: As of 7.2, Vertica can automatically enforce primary and unique key constraints. See the documentation for more information.

Oracle DISTINCT NUMERIC - NOT DISTINCT CLOB; ORA-00932 [duplicate]

This question already has an answer here:
Oracle get DISTINCT numeric with a CLOB in the query
(1 answer)
Closed 8 years ago.
Refer to this question.
I am interested in selecting a DISTINCT NUMERIC from EVENTLOG that has an accompanying CLOB from EVENT_INFO_DETAIL that is not intended to be a DISTINCT selection.
In other words, I am interested in selecting a DISTINCT EVENTID_NBR because of the presence of multiple of the same number and to also see the CLOB associated with that DISTINCT EVENTID_NBR. I am NOT trying to select a DISTINCT CLOB in any way. How might I go about doing this?
For example, a result set could look like the following:
EVENID_NBR INPUT_ARGS (BYTE SIZE)
143 4096
143 3284
143 2162
143 2222
143 1024
I would want only one EVENTID_NBR because I need a representative sample in my result set but I also need the CLOB selected along with that DISTINCT EVENTID_NBR.
Is there a way to select just the first ROWID of each EVENTID_NBR that also include the associated CLOB?
Should I select a DISTINCT EVENTID_NBR and then try to find the CLOB associated with the EVENTID_NBR I have chosen?
This is typically done with a window function:
select evenid_nbr,
input_args
from (
select evenid_nbr,
input_args,
row_number() over (partition by evenid_nbr order by rowid) as rn
from event_info_detail
) t
where rn = 1
By changing the order by part you can adjust which evenid_nbr gets returned.

Declarative integrity constraint between rows without pivot

I have a situation like the following join table:
A_ID B_ID
1 27
1 314
1 5
I need to put a constraint on the table that will prevent a duplicate group from being entered. In other words:
A_ID B_ID
2 27
2 314
2 5
should fail, but
A_ID B_ID
3 27
3 314
should succeed, because it's a distinct group.
The 2 ways I've thought of are:
Pivot the table in a materialize view based upon the order and put a unique key on the pivot fields. I don't like this because in Oracle I have to limit the number of rows in a group because of both the pivoting rules, and the 32-column index limitation (thought of a way around this second problem, but still).
Create some unique hash value on the combination of the B_IDs and make that unique. Maybe I'm not enough of a mathematician, but I can't think of a way to do this that doesn't limit the number of values that I can use for B_ID.
I feel like there's something obvious I'm missing here, like I could just add some sort of an ordering column and set a different unique key, but I've done quite a bit of reading and haven't come up with anything. It might also be that the data model I inherited is flawed, but I can't think of anything that would give me similar flexibility.
Firstly a regular constraint can't work.
If the set with A_ID of 1 exists, and then session 1 inserts a record with A_ID 2 and B_ID of 27, session 2 inserts (2,314) and session 3 inserts (2,5), then none of those would see a conflict to cause a constraint violation. Triggers won't work either. Equally, if a set existed of (6,99), then it would be difficult for another session to create a new set of (6,99,300).
The MV with 'refresh on commit' could work, preventing the last session from successfully committing. I'd look more at the hashing option, summing up the hashed B_ID's for each A_ID
select table_name, sum(ora_hash(column_id)), count(*)
from user_tab_columns
group by table_name
While hash collisions are possible, they are very unlikely.
If you are on 11g check out LISTAGG too.
select table_name, listagg(column_id||':') within group (order by column_id)
from user_tab_columns
group by table_name

Resources