How to automatically generate unique id in SQL like UID12345678? - sql

I want to automatically generate unique id with per-defined code attach to it.
ex:
UID12345678
CUSID5000
I tried uniqueidentifier data type but it generate a id which is not suitable for a user id.
Any one have suggestions?

The only viable solution in my opinion is to use
an ID INT IDENTITY(1,1) column to get SQL Server to handle the automatic increment of your numeric value
a computed, persisted column to convert that numeric value to the value you need
So try this:
CREATE TABLE dbo.tblUsers
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
UserID AS 'UID' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,
.... your other columns here....
)
Now, every time you insert a row into tblUsers without specifying values for ID or UserID:
INSERT INTO dbo.tblUsersCol1, Col2, ..., ColN)
VALUES (Val1, Val2, ....., ValN)
then SQL Server will automatically and safely increase your ID value, and UserID will contain values like UID00000001, UID00000002,...... and so on - automatically, safely, reliably, no duplicates.
Update: the column UserID is computed - but it still OF COURSE has a data type, as a quick peek into the Object Explorer reveals:

CREATE TABLE dbo.tblUsers
(
ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
UserID AS 'UID' + RIGHT('00000000' + CAST(ID AS VARCHAR(8)), 8) PERSISTED,
[Name] VARCHAR(50) NOT NULL,
)
marc_s's Answer Snap

Reference:https://learn.microsoft.com/en-us/sql/t-sql/functions/newid-transact-sql?view=sql-server-2017
-- Creating a table using NEWID for uniqueidentifier data type.
CREATE TABLE cust
(
CustomerID uniqueidentifier NOT NULL
DEFAULT newid(),
Company varchar(30) NOT NULL,
ContactName varchar(60) NOT NULL,
Address varchar(30) NOT NULL,
City varchar(30) NOT NULL,
StateProvince varchar(10) NULL,
PostalCode varchar(10) NOT NULL,
CountryRegion varchar(20) NOT NULL,
Telephone varchar(15) NOT NULL,
Fax varchar(15) NULL
);
GO
-- Inserting 5 rows into cust table.
INSERT cust
(CustomerID, Company, ContactName, Address, City, StateProvince,
PostalCode, CountryRegion, Telephone, Fax)
VALUES
(NEWID(), 'Wartian Herkku', 'Pirkko Koskitalo', 'Torikatu 38', 'Oulu', NULL,
'90110', 'Finland', '981-443655', '981-443655')
,(NEWID(), 'Wellington Importadora', 'Paula Parente', 'Rua do Mercado, 12', 'Resende', 'SP',
'08737-363', 'Brasil', '(14) 555-8122', '')
,(NEWID(), 'Cactus Comidas para Ilevar', 'Patricio Simpson', 'Cerrito 333', 'Buenos Aires', NULL,
'1010', 'Argentina', '(1) 135-5555', '(1) 135-4892')
,(NEWID(), 'Ernst Handel', 'Roland Mendel', 'Kirchgasse 6', 'Graz', NULL,
'8010', 'Austria', '7675-3425', '7675-3426')
,(NEWID(), 'Maison Dewey', 'Catherine Dewey', 'Rue Joseph-Bens 532', 'Bruxelles', NULL,
'B-1180', 'Belgium', '(02) 201 24 67', '(02) 201 24 68');
GO

If you want to add the id manually you can use,
PadLeft() or String.Format() method.
string id;
char x='0';
id=id.PadLeft(6, x);
//Six character string id with left 0s e.g 000012
int id;
id=String.Format("{0:000000}",id);
//Integer length of 6 with the id. e.g 000012
Then you can append this with UID.

The 'newid()' method unique id generate for per record.
AddColumn("dbo.Foo", "Key", c => c.String(nullable: false, maxLength: 250, defaultValueSql: "newid()"));

Table Creating
create table emp(eno int identity(100001,1),ename varchar(50))
Values inserting
insert into emp(ename)values('narendra'),('ajay'),('anil'),('raju')
Select Table
select * from emp
Output
eno ename
100001 narendra
100002 rama
100003 ajay
100004 anil
100005 raju

Related

Change "money" symbol on Beekeeper SQL

I'm student of SQL using Beekeeper Studio/Postgres, and I need to create a column using money.
But when I do SELECT * FROM produto, shows me "R$", my local monetary symbol.
Can I change the R$ to ʛ not only in my Beekeeper, but to everyone?
CREATE TABLE produto(
id SERIAL PRIMARY KEY,
codigo_produto int NOT NULL,
nome_produto VARCHAR(100) NOT NULL,
descricao_produto VARCHAR(100) NOT NULL,
estoque_produto int NOT NULL,
fabricacao_produto date NOT NULL,
valor_produto money NOT NULL
);
INSERT INTO produto (codigo_produto, nome_produto, descricao_produto, estoque_produto, fabricacao_produto, valor_produto) values
(1, 'firebolt', 'vassoura randolph spudmore', 1, '1993-02-08', '2000'),
(2, 'cleansweep eleven', 'vassoura companhia de vassouras cleansweep', 15, '1995-08-01', '500');
SELECT * FROM produto

SQL Server : default constraint doesn't work

I have a small problem with my code. I added a default constraint but for some reason it doesn't want to work. My code:
CREATE TABLE oc.students
(
stud_id INT PRIMARY KEY IDENTITY (1,1),
first_name VARCHAR(50) NOT NULL,
mid_name VARCHAR(50),
last_name VARCHAR(50) NOT NULL,
DOB DATE,
email VARCHAR (255) NOT NULL,
country VARCHAR(50) NOT NULL,
phone VARCHAR(20),
reg_date DATE NOT NULL
);
ALTER TABLE oc.students
ADD DEFAULT GETDATE() FOR [reg_date];
INSERT INTO oc.students (first_name, mid_name, last_name, DOB, email, country, phone, reg_date)
VALUES ('John', '', 'Smith', '1986-12-24', 'js#gmail.com', 'Malta', 123456789, '')
SELECT *
FROM oc.students
Result:
What could be the problem?
'' and NULL are not the same (well, in any database other than Oracle). The first is a string that happens to have no characters. The second is a SQL constant value that has the semantics of "unknown value" and is often used for missing values.
You are inserting '' which is interpreted as 0, which gets converted to the base date. Actually, the technical term for this is epoch, which is the date a uses to start counting date/time values.
If you want the default, you can use:
VALUES (
'John',
'',
'Smith',
'1986-12-24',
'js#gmail.com',
'Malta',
123456789,
DEFAULT
)
Or, more commonly, the column is just left out:
INSERT INTO oc.students (
first_name,
mid_name,
last_name,
DOB,
email,
country,
phone)
VALUES (
'John',
'',
'Smith',
'1986-12-24',
'js#gmail.com',
'Malta',
123456789
)

Why am I getting SQL Error 42x80?

CREATE TABLE customer (
customer_id INT NOT NULL generated always AS identity(start WITH 1, increment BY 1) CONSTRAINT customers_pk PRIMARY KEY
,cFirstname VARCHAR(20) NOT NULL
,cLastname VARCHAR(20) NOT NULL
,cPhone VARCHAR(20) NOT NULL
,cstreet VARCHAR(50)
,czipcode VARCHAR(5)
,CONSTRAINT customers_uk01 UNIQUE (
cFirstname
,cLastname
,cPhone
)
);
INSERT INTO customer (
cFirstname
,cLastname
,cPhone
,cstreet
,czipcode
)
VALUES (
'Dave'
,'Brown'
,'562-982-8696'
,'123 Lakewood Blvd. Long Beach'
,'90080'
)
,(
'Rachel'
,'Burris'
,'213-543-2211'
,'54 218th St. Torrance'
,'90210'
)
,(
'Tom'
,'Jewett'
,'714-555-1212'
,'10200 Slater'
,'92708'
)
,(
'Alvero'
,'Monge'
,'562-111-1234'
,'314159 Pi St. Long Beach'
,'90814'
),);
I'm getting the error at the line "insert into customer".
[Exception, Error code 30,000, SQLState 42X80] VALUES clause must
contain at least one element. Empty elements are not allowed.
What is causing the error?
Remove the extra ,) at the end of your query:

SQL Server constraint to check other columns

Product: SQL Server
Is it possible to write a constraint, that checks the values of other columns? In my specific case I will give you an example:
Let's imagine I have a table with 5 Columns:
Name | Hobby1 | Hobby2 | Hobby3 | Hobby4
Lets say there are the following values in it:
John Doe| fishing | reading| swimming| jogging
What I try to reach is the following:
If someone trys to Insert : John Doe, fishing,reading
It should be blocked, cause I don't want the same combination in the first 3 Columns.
Can I realise that with a constraint or do I need a Primary key combination for the first 3 columns?
Thanks for your replies.
Add unique constraint to your table for first three columns.
ALTER TABLE YourTableName
ADD CONSTRAINT UK_Name_Hobby1_Hobby2 UNIQUE (Name, Hobby1,Hobby2);
Well, you could do as #jarlh says (in comments) and ensure the hobby columns are ordered and this will satisfy your requirements:
CREATE TABLE Hobbies
(
Name VARCHAR(35) NOT NULL,
Hobby1 VARCHAR(35) NOT NULL,
Hobby2 VARCHAR(35) NOT NULL,
Hobby3 VARCHAR(35),
Hobby4 VARCHAR(35),
CHECK ( Hobby1 < Hobby2 ),
CHECK ( Hobby2 < Hobby3 ),
CHECK ( Hobby3 < Hobby4 ),
UNIQUE ( Name, Hobby1, Hobby2 ),
);
...However, this would allow the following which feels like it should be invalid data:
INSERT INTO Hobbies VALUES ( 'John Doe', 'fishing', 'jogging', 'reading', 'swimming' );
INSERT INTO Hobbies VALUES ( 'John Doe', 'jogging', 'reading', 'swimming', NULL );

SQL performance width versus depth

I have a customers table that holds information about customer prefrences like if he wants to receive a newsletter and so on. If he/she wants to receive a newsletter, the value is stored in the column "customerNewsletter" and set to true. However I have a couple of these bit values and parameters that are in a column of there own. I store dates, true/false, integers and tekst like this for each customer.
I find that about 80% of my customers wants to receive a newsletter and that makes that 80% of the values is set to true. I now store a value for each customer set to false or true. What if I only should have to store the 20% set to false ??
There is a list of about 20 of these parameters that I could include as a column (they are now), but I was wondering if there is a better way.
So I create 3 tables to hold these parameter values, a param table holding the actual value, a paramsNames table, that holds the names of the values and a params table that connects the parameters to a customerID
SELECT
customerParamsName as [Name],
customerParamText as [Text],
customerParamINT as [int],
customerParamsDateTime as [Date]
FROM db14.customerParams
INNER JOIN db14.customerParam ON customerParamsChildID = customerParamID
INNER JOIN db14.customerParamsNames ON customerParamNameID = customerParamsNameID
This would give me
Name Text int Date
Phonenumber NULL 615164898 2013-09-20 00:00:00.000
Can anyone tell me if this is a good way to go, or are there more common ways of storing Multi-Type parameters more efficiently ?
AFTER some MORE consideration
I have created 2 tables
customerParam
paramID paramNameID ParamParentID paramChildID paramText paramINT paramDate
INT TINYINT INT INT varchar(24) INT DATETIME
PRIMARY INDEXED
customerParamNames
paramNameID paramName
TINYINT VARCHAR(24)
PRIMARY
1 'FirstName'
2 'LastName'
3 'Email Address'
4 'Phonenumber'
5 etc..
Let's say I want to store the firstName and LastName
I create records in customerParam for both values ;
paramID paramNameID ParamParentID paramChildID paramText paramINT paramDate
17456 1 'John'
17467 2 'Doo'
17468 1 752 17456
17469 2 752 17467
As I expect more occurrences for the name ‘John’ I am storing it as an independent value, then joining it using the parentID/ChildID combination.
and for the phoneNumber
17470 4 752 31615164899
17471 5 752 'me#here.com'
The phonenumber is very explicit to this customer, I am using the parentID to join it straight to the customer. The same goes for the emailaddress.
At this time this solution looks like the way to go... I am also still looking at the xml approach but I don’t have a good understanding on how to use XQuery and xmlDocuments stored in a database.
And It seems like a lot of overhead.
I will move forward with the solution above... until someone gives me a better one.
Example SQL
DECLARE #paramNames TABLE (paramNameID TINYINT, paramName varchar(24))
DECLARE #param TABLE (paramID INT, paramNameID TINYINT, paramParentID INT, paramChildID INT, paramText varchar(24), paramINT INT, paramDate datetime)
INSERT INTO #paramNames VALUES ( 1, 'firstname')
INSERT INTO #paramNames VALUES ( 2, 'lastname')
INSERT INTO #paramNames VALUES ( 3, 'emailaddress')
INSERT INTO #paramNames VALUES ( 4, 'phonenumber')
select * from #paramNames
INSERT INTO #param VALUES (1, 1, Null, Null, 'John' , Null, Null)
INSERT INTO #param VALUES (2, 2, Null, Null, 'Doo' , Null, Null)
INSERT INTO #param VALUES (3, 1, 752, 1, Null , Null, Null)
INSERT INTO #param VALUES (4, 2, 752, 2, Null , Null, Null)
INSERT INTO #param VALUES (5, 4, 752, Null, Null , 615164899, Null)
INSERT INTO #param VALUES (5, 3, 752, Null, 'me#here.com' , Null, Null)
select
a.paramParentID, b.paramName, c.paramText, c.paramINT, c.paramDate
from #param a
inner join #paramNames b on a.paramNameID = b.paramNameID
inner join #param c on a.paramChildID = c.paramID
UNION ALL
select
a.paramParentID, b.paramName, a.paramText, a.paramINT, a.paramDate
from #param a
inner join #paramNames b on a.paramNameID = b.paramNameID
WHERE paramParentID IS NOT NULL
AND paramChildID IS NULL
giving the result
paramParentID paramName paramText paramINT paramDate
752 firstname John NULL NULL
752 lastname Doo NULL NULL
752 phonenumber NULL 615164899 NULL
752 emailaddress me#here.com NULL NULL
I would approach this a little differently if you have performance and flexibility in mind.
USE Test;
CREATE TABLE Customers
(
CustomerID INT NOT NULL CONSTRAINT PK_Customers
PRIMARY KEY CLUSTERED IDENTITY(1,1)
, CustomerName NVARCHAR(255)
);
CREATE TABLE CustomersReceivingEmails
(
CustomerID INT NOT NULL CONSTRAINT FK_CustomerID
FOREIGN KEY REFERENCES Customers (CustomerID)
ON DELETE CASCADE ON UPDATE CASCADE
, EmailAddress NVARCHAR(255) NOT NULL
CONSTRAINT PK_CustomersReceivingEmails
PRIMARY KEY CLUSTERED (CustomerID, EmailAddress)
);
INSERT INTO Customers (CustomerName) VALUES ('Max');
INSERT INTO Customers (CustomerName) VALUES ('Mike');
INSERT INTO CustomersReceivingEmails (CustomerID, EmailAddress)
VALUES (1, 'us#them.com');
INSERT INTO CustomersReceivingEmails (CustomerID, EmailAddress)
VALUES (1, 'us#me.com');
/* ALL Customers */
SELECT * FROM Customers;
/* Only customers who wish to receive Emails, allows a given customer
to have multiple email addresses */
SELECT C.CustomerName, E.EmailAddress
FROM Customers C
INNER JOIN CustomersReceivingEmails E ON C.CustomerID = E.CustomerID
ORDER BY C.CustomerName, E.EmailAddress;
The SELECT returns rows like this:
This allows the Customers table to contain all customers regardless of their preference for emails.
The CustomersReceivingEmails table has a foreign key to Customers.CustomerID for customers who want to receive emails.
Your second solution is a variant of what is commonly known as Entity-Attribute-Value data model. This approach appears to be flexible. However, it essentially generates a schema within schema and is very slow to query as the number of attributes increases
If you're storing a lot of identical values, have a look at columnstore indexes. They work well in scenarios where selectivity is low (lots of rows & only a small number of distinct values)