inserting id into table with random number - sql

I need to write a view that does a merge insert/update.
When inserting, I need to insert id.
This id is also being inserted by random number generator in another program ( which I can't change ).
I wanted to do max(id) + 1, but not sure if that is a good idea. Could you suggest any better solutions for this problem?
or
How about using with id as ( dbms_random .... ) do a
select * from table where id = ?
if row is not found, I will insert this id otherwise, I will generate another random and do a select.

if this is for a Primary Key - then how about generating negative numbers for your part of the app (using a sequence) and leaving the random number wizardry in the positives...

You can use rand() function for your request with random number !
Enjoy,
remontees

Related

How can I update the value of a field in a table to be a random number that's unique most of the time?

I have a simple table:
CREATE TABLE [dbo].[Word] (
[WordId] INT IDENTITY (1, 1) NOT NULL,
[NameId] INT NOT NULL
PRIMARY KEY CLUSTERED ([WordId] ASC)
);
I have a unique index on NameId
I am trying to update this table and change one column to a random number:
UPDATE Word SET NameId = ROUND(RAND()*2147483647,0)
I realize there is a very very small chance this will not work but it's actually failing every time even though the table has only a very small number of rows the update always fails and says there's a duplicate.
Can anyone tell me what's happening here and also suggest a way to update this table so that there's no duplicate values of NameId created most of the time.
You are updating every NameId with same value, use WHERE statement to update only one row
EDIT: This should do the trick you are looking for, NewId() generates new id for each row
UPDATE Word SET NameId = abs(checksum(NewId()) % 2147483647)
How many rows do you have? It could be a case of the birthday paradox.
Have you tried doing this:
SELECT ROUND(RAND()*2147483647,0) FROM Word
Do the numbers really need to be pseudo-random? You could use row_number() to make them increment.

Oracle SQL: How to generate per-order sequence numbers

I would like to generate unique sequence numbers for each order comment as they are entered.
For example, the segment:
INSERT INTO order_comments(order_number,
seq_num,
comment_text,
remark_timestamp)
VALUES (
'Smith',
(SELECT NVL (MAX (seq_num), 0) + 1
FROM order_comments
WHERE order_number='141592'),
'Shipped updated version 1.1’,
current_timestamp);
can be run multiple times, getting a new sequence number for that user each time.
The bad news is when this is written in Pro*C and we have multiple copies running simultaneously, we seem to get locks if we try to insert two comments for the same user at the same time. We could have an order_comment_sequence and just use nextval in the insert but that seems untidy since the “141592” comments will not have sequential numbers.
For the sake of the current discussion, we will say we have a few million orders, each of which will have five or ten comments. The order_number and seq_num are the primary key.
Is there something wrong with doing it this way? Is there an easier way of doing it?
You can use Oracle Sequence.
First create the sequence, like this:
CREATE SEQUENCE order_comments_seq
MINVALUE 1
MAXVALUE 999999999999999999999999999
START WITH 1
INCREMENT BY 1
CACHE 20;
For more info: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_6015.htm#SQLRF01314
then you can use sequence.NEXTVAL like this:
INSERT INTO order_comments(order_number,
seq_num,
comment_text,
remark_timestamp)
VALUES ( 'Smith',
order_comments_seq.NEXTVAL,
'Shipped updated version 1.1’,
current_timestamp);
I don't think you can avoid the "untidy" approach if you want to avoid locks. You can generate a sequence number by ORDER_NUMBER when retrieving data from the database as follows:
SELECT order_number, ROW_NUMBER() OVER ( PARTITION BY order_number ORDER BY remark_timestamp ) AS seq_num
FROM order_comments
The "sequence" approach given by #benji is one approach. Another is to generate a random number using SYS_GUID():
TO_NUMBER( SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' )
You could even use this on the SEQ_NUM column as a default:
ALTER TABLE order_comments MODIFY seq_num DEFAULT TO_NUMBER( SYS_GUID(), 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' );
Hope this helps.

Can Sql Server generate a unique 13 digit number

I need to generate a unique 13 digit number.
Can Sql Server generate this number for me somehow if I create a table with the 13 digit number as a primary key?
Update
I want the number to look like a random number, so not an autoincrementing number.
It has to be 13 digits, and it shouldn't be auto-incrementing, and it should be unique. The number shouldn't have many zero's in it but it can contain numbers from 0-9.
This number should look like a credit card number, so no trailing zeros.
My suggestion would be to have an identity column on the table that auto-increments. Then, define your value based on this. A simple way would be:
create table t (
tId int identity(1, 1) not null,
. . .
myId cast(rand(tId)*10000000000000 as varchar(13))
)
This shows it as a computed column. Of course, you can assign the value when each row is created. This is not guaranteed to produce different results, but it is highly, highly unlikely that you would see a collision.
The following is an alternative is also not guaranteed, but might work:
create table t (
tId varchar(13) default cast(cast(rand(checksum(getdate())*10000000000000 as bigint) as varchar(13)
. . .
)
EDIT:
The chance of a collision is a bit higher than I expected -- my intuition on 13-digit hash codes is, I guess, not what it should be.
In any case, there are two sources of collisions. The first is the random number generator producing the same value. To handle that, just make the assumption that the random number generator in conjunction with checksum() really is random. So, the question is: What is the chance of two random numbers less than 10,000,000,000,000 being the same value? I'll let interested parties search the web for a formula to calculate this.
If you generate 1,000 numbers. Then the probability is basically 0% that any two would be the same. That is, you are safe for the first 1000 numbers, if you assume they are distinct. Here is a summary:
1,000 0.0000%
10,000 0.0005%
100,000 0.0500%
1,000,000 4.8771%
10,000,000 99.3262%
Up to a few hundred thousand values, you are probably pretty safe. When you get into the millions -- even the low millions -- the chance of collision increases substantially.
At some point, if you want lots and lots of unique values, you are going to have to create a table that contains the unique values and a process for choosing a value not in the table.
As John Barça points out: Do not use this method for cat photos on Facebook.
Just create a Guid (select newid() ) & parse it... remove the { and the '-' & do a length of 13 select on it.
I use a similar method to generate random/unique table names in a reporting system. It might do the trick for you. Just adjust the multiplier to impact the final integer length.
SELECT CONVERT(BIGINT,RAND()*10000000000000)
As a table...
CREATE TABLE #test (testID INT,
UniqueID AS CONVERT(BIGINT,RAND()*10000000000000))
INSERT INTO #test (testID)
SELECT 1
SELECT * FROM #TEST
DROP TABLE #test
Just insert a value into testID (can be 1 every time) and a new UniqueID will generate. You should have a primary key on any production table though.
NB: While the chances of a duplicate ever happening are very small, it could still happen.
SELECT CEILING(RAND()*9999999999999)
something like this might work:
use [chamomile];
go
if object_id(N'[utility].[table_01]', N'U') is not null
drop table [utility].[table_01];
go
if object_id(N'[utility].[generate_random_sequence]', N'FN') is not null
drop function [utility].[generate_random_sequence];
go
/*
select [utility].[generate_random_sequence] (rand());
*/
create function [utility].[generate_random_sequence] (
#random [float])
returns [bigint]
as
begin
declare #return [bigint] = ceiling(#random * 9999999999999);
while #return > 9999999999999
or #return < 1000000000000
set #return = ceiling(#random * 9999999999999);
return #return;
end;
go
if object_id(N'[utility].[table_01]', N'U') is not null
drop table [utility].[table_01];
go
create table [utility].[table_01] (
[my_id] as [utility].[generate_random_sequence] (rand())
, [flower] [sysname]
);
go
insert into [utility].[table_01]
([flower])
values (N'rose');
select *
from [utility].[table_01];

select max value of a column in table with no rows

I am using oracle database
While inserting a row in a table, i need to find the max value of a column and increment it by 1, and use that value in row i am inserting.
INSERT INTO dts_route
(ROUTE_ID, ROUTE_UID, ROUTE_FOLDER)
VALUES (
(SELECT MAX(ROUTE_ID) + 1 FROM route) ,
ROUTE_UID,
ROUTE_FOLDER)
This works fine if their is at least one entry in table.
But returns null when their are no entries in table.
How can i get default value of 1 when their are no entries in table.
SELECT COALESCE(MAX(ROUTE_ID),0) ...
This is not a safe way of creating an auto-increment field. You can use an Oracle sequence to achieve this goal.
As for the null, you can use NVL to give a default value (say, 0) in case the function returns null.
Use sequence for the ID. You need to create sequence. See below link
http://www.basis.com/onlinedocs/documentation/b3odbc/sql_sequences.htm
Use:
INSERT INTO dts_route
(ROUTE_ID)
SELECT COALESCE(MAX(r.route_id), 0) +1
FROM ROUTE r
...but you really should be using a sequence to populate the value with a sequential numeric value:
CREATE SEQUENCE dts_route_seq;
...
INSERT INTO dts_route
(ROUTE_ID)
SELECT dts_route_seq.NEXTVAL
FROM DUAL;
Set a default for NULL
SELECT NVL(MAX(ROUTE_ID),0)
though using a sequence might be easier if you don't mind the odd gaps in your route ids
select 0 when null, then it will be 0+1 which is a correct number compared to null+1
SELECT isnull(MAX(ROUTE_ID),0) + 1 FROM route
If you are concerned about there being gaps in your route ids then create the sequence with the NOCACHE clause:
CREATE SEQUENCE dts_route_seq NOCACHE;
Note that there is a performance hit because Oracle now has to "commit" each time you increment the sequence.

Generating Random ID's in Microsoft SQL Server

I want to create a table in sql server and fill it up with data (people's info) every person should have a unique ID different than the auto incremented ID's by sql server
For example i need the ID for the first person inserted like this: 2016xxxx
how to fix the 2016 and randomly generate the numbers after that to be filled instead of xxxx
should i use a regular expression ?
You can also create a computed column like below
CREATE TABLE tableName
(
PkAutoId INT PRIMARY KEY IDENTITY(1,1),
PersonUniqueNo AS (CAST(DATEPART(YEAR,GETDATE()) AS VARCHAR) + RIGHT(RIGHT(CAST(RAND() AS VARCHAR),4) + CAST(PkAutoId AS VARCHAR),4))
)
Computed Column "PersonUniqueNo" is 8 Digit Unique Number comprising of Current Year And Conceited value of Random number and Primary Key Id for 4 Length, Total length will be 8 as asked.
You could create a function that would get the next value for you and use that instead of an AUTO_INCREMENT field.
I wouldn't recommend it tho. You shouldn't format the data like that before inserting it. That sort of thing should be done on the way out, preferably by the front-end code. Or you can just write a query and create a view ...
However if you must do that here is the complete answer with the code:
Is there a way to insert an auto-incremental primary id with a prefix in mysql database?