In SQL, how to populate number in sequence in column without alter the table structure? - sql

populating number in a sequence for a column without altering table structure--need a query

if you don't want to change or alter the database table structure, you have limited solutions actually.
First option might be using a sequence object
create sequence mySequence increment by 1;
After you have a sequence object, you can read from this sequence whenever you need this field value
select mySequence.nextval from dummy;
Unfortunately, each read will increment the current value of the sequence.
This means if you read but did not insert the value into the table, next time you insert a new row there will be a gap in your table column.
Or if you insert two rows from two different executions, one might read the sequence first but insert value later than the other thread; then the sequence will be like 11,12,14,13,15
Second option is creating a database table trigger AFTER INSERT statement.
Then you can the max value from table column (or can store in a separate table) or from sequence, and update the column field with this sequence data

Related

SQL Insert Row In-between Two Rows

How do I insert a row between here?
Data is not intended to be stored SQL tables in any particular order, so it's not appropriate to insert a row at a particular position. You use an SQL SELECT query to extract the data you want and ORDER BY to specify how it is sorted. If you really want to have this row in a particular position, add an ID column as the primary key and number the ID column values in the sequence that you want. Whatever you are using to view your rows will order them by the ID column by default. However, you're going to experience this same problem every time you want to add a new row as SQL tables are not intended to be used in this way.

Adding a computed column that uses MAX

I need to create a sequential number column for record number proposes
I am OK with losing sequence if I delete a row from the middle of the table
For example
1
2
3
If I delete 2, I am ok with new column been 4.
I tried to alter my table to
alter table [dbo].[mytable]
add [record_seq] as (MAX(record_seq) + 1)
but I am getting An aggregate may not appear in a computed column expression or check constraint.
Which is a bit confusing? do I need to specify an initial value? is there a better way?
If you're looking to allocate a sequence number even in cases where the table doesn't get a record inserted, I would handle it in the process responsible for performing those inserts. Create another table, in this table keep track of the max identity value of that sequence. Each time you want to perform an insert, reserve the sequence number you want by updating that table first. If you rely on selecting the max existing value, you could be at risk of multiple sessions getting the same "new" sequence number before inserting. Even if the insert fails, you will have incremented that control table so nothing else uses that value that has been reserved.
Its not supported in MsSql. You can use identity column:
ALTER TABLE [dbo].[mytable]
ADD [record_seq] INT IDENTITY
Or use trigger to update your seq column after insert and/or delete

Unique sequence for a column in oracle table

I am trying to load a table where i have a PK column called E_id. I want to generate a unique ID for this column every time a row is loaded into this table at informatica level. But i want this e_id column to generate a unique value at table level. Can i achieve this by writing a query to this column at table create script itself?
Currently i tried this method of defaulting the value with this
e_id NUMBER DEFAULT TO_NUMBER(TO_CHAR(SYSTIMESTAMP, 'YYYYMMDDHH24MISSFF9')) NOT NULL
Although at times i am getting the same value for two records.
Can someone help how to go about this?
TIA.
one of the most common way to do this is using sequences
1 create sequence
2 before insert row trigger that will populate value into the pk column
create sequence GSEQUENCE
minvalue 1000
maxvalue 99999999999999999
start with 93581
increment by 1
cache 20;
CREATE OR REPLACE TRIGGER BI_DOCUMENTS
BEFORE INSERT
on DOCUMENTS
for each row
declare numrows INTEGER;
begin
select gsequence.nextval
into :new.id_DOCUMENT
from dual;
end;
/
If you are using 12c the easiest way is to use an IDENTITY column. Oracle will automatically generate a unique value for the column whenever you insert a record.
In prior versions you can define a sequence and generate it via a trigger or reference it directly in the insert statement.
You mention Informatica. Its a long time since I used it but I seem to remember there being a simple way to generate a unique ID using Informatica too.
You can use Globally Unique ID (GUID) which is unique for all practice purpose. Lot of systems use GUID to generate unique id.
select sys_guid() from dual
Mote into here
While GUID gives truly random unique ids, you can always use Oracle sequence if you need sequential unique values.
Oracle doesn't have "auto increment" columns, but you can achive similar results by a trigger.
EDIT: You can refer this link too How to generate a GUID in Oracle?

Column Copy and Update vs. Column Create and Insert

I have a table with 32 Million rows and 31 columns in PostgreSQL 9.2.10. I am altering the table by adding columns with updated values.
For example, if the initial table is:
id initial_color
-- -------------
1 blue
2 red
3 yellow
I am modifying the table so that the result is:
id initial_color modified_color
-- ------------- --------------
1 blue blue_green
2 red red_orange
3 yellow yellow_brown
I have code that will read the initial_color column and update the value.
Given that my table has 32 million rows and that I have to apply this procedure on five of the 31 columns, what is the most efficient way to do this? My present choices are:
Copy the column and update the rows in the new column
Create an empty column and insert new values
I could do either option with one column at a time or with all five at once. The columns types are either character varying or character.
The columns types are either character varying or character.
Don't use character, that's a misunderstanding. varchar is ok, but I would suggest just text for arbitrary character data.
Any downsides of using data type "text" for storing strings?
Given that my table has 32 million rows and that I have to apply this
procedure on five of the 31 columns, what is the most efficient way to do this?
If you don't have objects (views, foreign keys, functions) depending on the existing table, the most efficient way is create a new table. Something like this ( details depend on the details of your installation):
BEGIN;
LOCK TABLE tbl_org IN SHARE MODE; -- to prevent concurrent writes
CREATE TABLE tbl_new (LIKE tbl_org INCLUDING STORAGE INCLUDING COMMENTS);
ALTER tbl_new ADD COLUMN modified_color text
, ADD COLUMN modified_something text;
-- , etc
INSERT INTO tbl_new (<all columns in order here>)
SELECT <all columns in order here>
, myfunction(initial_color) AS modified_color -- etc
FROM tbl_org;
-- ORDER BY tbl_id; -- optionally order rows while being at it.
-- Add constraints and indexes like in the original table here
DROP tbl_org;
ALTER tbl_new RENAME TO tbl_org;
COMMIT;
If you have depending objects, you need to do more.
Either was, be sure to add all five at once. If you update each in a separate query you write another row version each time due to the MVCC model of Postgres.
Related cases with more details, links and explanation:
Updating database rows without locking the table in PostgreSQL 9.2
Best way to populate a new column in a large table?
Optimizing bulk update performance in PostgreSQL
While creating a new table you might also order columns in an optimized fashion:
Calculating and saving space in PostgreSQL
Maybe I'm misreading the question, but as far as I know, you have 2 possibilities for creating a table with the extra columns:
CREATE TABLE
This would create a new table and filling could be done using
CREATE TABLE .. AS SELECT.. for filling with creation or
using a separate INSERT...SELECT... later on
Both variants are not what you seem to want to do, as you stated solution without listing all the fields.
Also this would require all data (plus the new fields) to be copied.
ALTER TABLE...ADD ...
This creates the new columns. As I'm not aware of any possibility to reference existing column values, you will need an additional UPDATE ..SET... for filling in values.
So, I' not seeing any way to realize a procedure that follows your choice 1.
Nevertheless, copying the (column) data just to overwrite them in a second step would be suboptimal in any case. Altering a table adding new columns is doing minimal I/O. From this, even if there would be a possibility to execute your choice 1, following choice 2 promises better performance by factors.
Thus, do 2 statements one ALTER TABLE adding all your new columns in on go and then an UPDATE providing the new values for these columns will achieve what you want.
create new column (modified colour), it will have a value of NULL or blank on all records,
run an update statement, assuming your table name is 'Table'.
update table
set modified_color = 'blue_green'
where initial_color = 'blue'
if I am correct this can also work like this
update table set modified_color = 'blue_green' where initial_color = 'blue';
update table set modified_color = 'red_orange' where initial_color = 'red';
update table set modified_color = 'yellow_brown' where initial_color = 'yellow';
once you have done this you can do another update (assuming you have another column that I will call modified_color1)
update table set 'modified_color1'= 'modified_color'

Filling incremental unqiue values for a newly created PK

I currently have a table with many rows, but no PK at all. I now require to have a unique, non-null, > 0 PK for every row.
I'm created the column for PK, but how I can I quickly fill in the column with an incremental value starting from 1?
Any method, a single SQL line, or a SQL line to be executed as many times as are rows are good enough for me.
Something like
update sometable set newkeyfield = Row_Number() Over();
should do not a DB2 bloke, but should be close.
Try using a DB2 Sequence object. They are designed for creating unique sequences of numbers. Pick your data type.
CREATE SEQUENCE mySeq as int;
You retrieve and increment the sequence in one step, using a sequence reference
NEXT VALUE FOR mySeq
You expression can use this in an INSERT, UPDATE, or MERGE, or most places you can use an expression.