Oracle SQL: How to read-and-increment a field
In this particular case, a sequence is the right solution as mentioned. But if in some future situation you need to both update something and return a value in the same statement, you can use the RETURNING
clause:
UPDATE atable SET foo = do_something_with(foo) RETURNING foo INTO ?
If the calling code is PL/SQL, replace the ? with a local PL/SQL variable; otherwise you can bind it as an output parameter in your program.
Edit: Since you mentioned Perl, something like this ought to work (untested):
my $sth = $dbh->prepare('UPDATE mytable SET idnext = idnext + 1 returning idnext into ?');
my $idnext;
$sth->bind_param_inout(1, \$idnext, 8);
$sth->execute; # now $idnext should contain the value
See DBI.
in oracle select query how to add a number column increment by 2 starting from 1
You know you have rownum available, but take a step back. You're starting with the contiguous sequence 1,2,3,4,5,6,... and you want to generate a sequence of odd numbers 1,3,5,7,9,11,.... So you need to figure out an algorithm that will convert one to the other.
If you say your starting number is n
then you want to generate m
where m=(2*n)-1
.
You can use rownum
(or row_number()
, etc.) to generate your n
values:
select column1, rownum as n
from your_table;
And you can then apply that algorithm:
select column1, (2*rownum)-1 as column2
from your_table;
COLUMN1 COLUMN2
------- ----------
amit 1
siva 3
pyll 5
jane 7
john 9
anna 11
...
With this simple approach the column2
values are not in the same order as the column1
values. You can either use row_number()
or rank()
instead, with a suitable order by
clause; or use a subquery which does the ordering and apply rownum (and this algorithm) outside that:
select column1, (2*rownum)-1 as column2
from (
select column1
from your_name
order by column1
);
or some other variation, depending on the result you want to end up with.
Increment column A when column B changes value
This is easy to do with the dense_rank()
function in the query used to fetch the results:
select name, hour, value,
dense_rank() over (order by name) as row_num
from t;
Note: this will not necessarily assign the values in the order you have given. But each group will get a different value. If you need them in the order given, then you will need to identify the order. SQL tables are inherently unordered, so a column is needed to specify the ordering.
Increment column values based on two columns in Oracle database
The NEW_RO column can be calculated with the analytic function ROW_NUMBER():
select ... ,
row_number() over (partition by cid order by ro) as new_ro [, ...]
In your data, there are ties for RO within the same CID. Do you care, in that case, which row gets what NEW_RO value? If, for example, in the case of same RO you also want to (further) order by ID, you can change the above to
select ... ,
row_number() over (partition by cid order by ro, id) as new_ro [, ...]
EDIT: I missed the fact that you need to UPDATE the RO values with the NEW_RO values. Analytic functions can't be used in an UPDATE
statement (not directly anyway); the MERGE
statement is the perfect alternative for this:
merge into test
using ( select id,
row_number() over (partition by cid order by ro, id) as new_ro
from test
) s
on (test.id = s.id)
when matched then update set ro = s.new_ro
;
Oracle - Insert New Row with Auto Incremental ID
To get an auto increment number you need to use a sequence in Oracle.
(See here and here).
CREATE SEQUENCE my_seq;
SELECT my_seq.NEXTVAL FROM DUAL; -- to get the next value
-- use in a trigger for your table demo
CREATE OR REPLACE TRIGGER demo_increment
BEFORE INSERT ON demo
FOR EACH ROW
BEGIN
SELECT my_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
How to create id with AUTO_INCREMENT on Oracle?
There is no such thing as "auto_increment" or "identity" columns in Oracle as of Oracle 11g. However, you can model it easily with a sequence and a trigger:
Table definition:
CREATE TABLE departments (
ID NUMBER(10) NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL);
ALTER TABLE departments ADD (
CONSTRAINT dept_pk PRIMARY KEY (ID));
CREATE SEQUENCE dept_seq START WITH 1;
Trigger definition:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/
UPDATE:
IDENTITY
column is now available on Oracle 12c:
create table t1 (
c1 NUMBER GENERATED by default on null as IDENTITY,
c2 VARCHAR2(10)
);
or specify starting and increment values, also preventing any insert into the identity column (GENERATED ALWAYS
) (again, Oracle 12c+ only)
create table t1 (
c1 NUMBER GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1),
c2 VARCHAR2(10)
);
Alternatively, Oracle 12 also allows to use a sequence as a default value:
CREATE SEQUENCE dept_seq START WITH 1;
CREATE TABLE departments (
ID NUMBER(10) DEFAULT dept_seq.nextval NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL);
ALTER TABLE departments ADD (
CONSTRAINT dept_pk PRIMARY KEY (ID));
Auto increment in Oracle SQL
If you use double quotes to create an object (and the object name is not all upper case), then you are forced to use double quotes everywhere you refer to it.
So in this case, this would work (notice the double quotes around Account_seq
):
INSERT INTO "Account" VALUES ("Account_seq".NEXTVAL, 'xxx', 'xxx', 'xxx', 'xxx', 'user');
That said, using double quotes everywhere is annoying. Instead, consider changing the sequence creation to avoid using double quotes:
CREATE SEQUENCE Account_seq ...
... that way, you can refer to it without double quotes and the sequence name won't be case sensitive.
EDIT
To clarify the case sensitivity part a little bit:
When you double quote an identifier, then Oracle looks for that identifier with that exact casing.
On the other hand, if you don't use double quotes, it will look for the equivalent identifier all upper-cased.
Example:
"Account_seq"
: it will look forAccount_seq
"AcCoUnT_SeQ"
: it will look forAcCoUnT_SeQ
Account_seq
: it will look forACCOUNT_SEQ
AcCoUnT_SeQ
: it will look forACCOUNT_SEQ
Related Topics
Sql Server Table Locks in Long Query - Solution: Nolock
Sequence Doesn't Exist Ora-02289
How to Insert Data Directly from Excel to Oracle Database
Sql Server 2012: Add a Linked Server to Postgresql
Creating Groups of Consecutive Days Meeting a Given Criteria
Most Efficient Method for Persisting Complex Types with Variable Schemas in Sql
How to Execute Different Select Statements Based on a Case
Execute Procedure in a Trigger
Error While Uploading a Report
How to Use Sum for Bit Columns
How to Execute SQL Statements in Command Prompt (Cmd)
Sql Create Database If Not Exists, Unexpected Behaviour
Django Annotate() Multiple Times Causes Wrong Answers
Why Can't I Reorder My SQL Server Columns
Display Zero by Using Count(*) If No Result Returned for a Particular Case