I am building a database and have set field A, Release #, as the primary field. I am running into a problem where duplicate keys are found which gives error on import.
Specifically, release # "49221" is the value of a certain release from a certain website. On a different website, the release # is "0000000049221"
Release# 49221 is a completely different release than is "0000000049221". Is there a way for me to import both of them into the same table while still retaining field "release #" as the primary key?
This usually happens when implicit conversions are given, check the type of your primary key.
For example:
CREATE TABLE TEST
(
COLUMN_1 INT,
COLUMN_2 VARCHAR(8)
)
INSERT INTO TEST
VALUES (4566,'00004566')
SELECT * FROM TEST WHERE COLUMN_1 = COLUMN_2
The second column , it converts to int, and the zeros at the left dissapear, Because zeros at the left in a number has not value (as you know).
Change the second column type to type varchar or char.
You would need to define the primary key as a CHAR or VARCHAR instead of an integer value.
Related
I need a unique number id for my table. Usually I would use Identity in Sql Server, but there is a catch to my use case. I would like to know the id before the row is created (to be able to reference it in other records in memory, before committing everything to the database).
I don't know if it's possible to achieve with Identity, but I could not figure that out.
So my next best guess is that I need a table that will store one value and keep incrementing it and returning me a new value for the id. Access would have to be locked so that no two operations can get the same value.
I am thinking of using e.g. sp_getapplock #Resource = 'MyUniqueId' to prevent same number from being returned to a caller. Perhaps I can use ordinary locking in transactions for that as well.
Is there any better approach to the problem?
You can create a SEQUENCE object that produces incrementing values. A SEQUENCE can be used independently or as a default value for one or more tables.
You can create a sequence with CREATE SEQUENCE :
CREATE SEQUENCE Audit.EventCounter
AS int
START WITH 1
INCREMENT BY 1 ;
You can retrieve the next value atomically with NEXT VALUE FOR and use it in multiple statements eg :
DECLARE #NextID int ;
SET #NextID = NEXT VALUE FOR Audit.EventCounter;
Rolling back a transaction doesn't affect a SEQUENCE. From the docs:
Sequence numbers are generated outside the scope of the current transaction. They are consumed whether the transaction using the sequence number is committed or rolled back.
You can use NEXT VALUE FOR as a default in multiple tables. In the documentation example, three different types of event table use the same SEQUENCE allowing all events to get unique numbers:
CREATE TABLE Audit.ProcessEvents
(
EventID int PRIMARY KEY CLUSTERED
DEFAULT (NEXT VALUE FOR Audit.EventCounter),
EventTime datetime NOT NULL DEFAULT (getdate()),
EventCode nvarchar(5) NOT NULL,
Description nvarchar(300) NULL
) ;
GO
CREATE TABLE Audit.ErrorEvents
(
EventID int PRIMARY KEY CLUSTERED
DEFAULT (NEXT VALUE FOR Audit.EventCounter),
EventTime datetime NOT NULL DEFAULT (getdate()),
EquipmentID int NULL,
ErrorNumber int NOT NULL,
EventDesc nvarchar(256) NULL
) ;
GO
CREATE TABLE Audit.StartStopEvents
(
EventID int PRIMARY KEY CLUSTERED
DEFAULT (NEXT VALUE FOR Audit.EventCounter),
EventTime datetime NOT NULL DEFAULT (getdate()),
EquipmentID int NOT NULL,
StartOrStop bit NOT NULL
) ;
GO
One option here would be to use a UUID to represent each unique record. Should you want to generate the UUID within SQL Server, you could use the NEWID() function (see the documentation for more information). If this value would be generated from your application code, you could convert it to uniqueidentifier type within SQL Server using CONVERT.
For reference, a UUID is a 16 byte unique identifier. It is extremely unlikely that your application or SQL Server would ever generate the same UUID more than once. They look like this:
773c1570-1076-4e19-b728-6d7b0b20895a
If you want a behaviour that matches the one of an IDENTITY column, try:
CREATE SEQUENCE mydb.dbo.mysequence;
And then, repeatedly:
SELECT NEXT VALUE FOR mysequence;
And , if you want to play some more, see here:
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-sequence-transact-sql?view=sql-server-ver15
happy playing ...
I have a table with a column nif which has to be exactly 9 digits long, after I tried to do:
CREATE TABLE fornecedor(
nif numeric(9) PRIMARY KEY,
nome varchar(64) NOT NULL,
CONSTRAINT nif_tamanho CHECK (length(to_char(nif, 'FM999MI')) = 9));
INSERT INTO fornecedor(nif, nome) VALUES (123456789, 'Pmsmm');
It returns an error saying:
ERROR: new row for relation "fornecedor" violates check constraint "nif_tamanho"
How do I make it so that the inserted number is verified having 9 digits exactly ?
Thanks in advance
As you mention in your comment, you need a string data type if you don't want to lose leading zeroes.
But I think that the correct solution depends on how you want to use the column. It is always good to choose the data type according to the column's semantics.
If you need to do arithmetic or numeric comparisons with the data, choose integer by all means (you can add a check constraint on nif < 100000000). You can always format the value with leading zeroes when you convert it to a string for output.
If you need to do string operations on the value (e.g. substrings), storing the data as a sting type is preferable.
I have just started with SQL and want to clear the basic keywords of SQL.
What is the difference between
"number" and "numeric" & "number & integer"?
While creating a table
Create table myTable
(
my_Id int(6) primary key
...
Above query Gives me an error suggesting to put null or not null before "primary key".
Do I always need to put either null or not null for the keyword integer?
If I replace int(6) with number(6), that statement works.
1."number" and "numeric" & "number & integer"?
An integer cannot take inputs such as 1.1 and the likes since float or decimal datatype handles this, while a number can take this both. I believe the reason why INT does not display it with a decimal its because its being rounded off try to input a 1.5 on an int column and you'll get a 2 instead
2.While creating a table
Create table myTable (
my_Id int(6) primary key, <--- Gives me an error suggesting to put
null or not null before "primary key". Do I always need to put either
null or not null for the keyword integer?
you need to either put a null or not null before a primary key unless I believe its been set into an Auto Increment
BTW my answer was based on MYSQL since that's what I used.. although I'm not sure if your using it since you didn't add any tags :)
for more info for this topic I think this could add a little more light to your inquiry
reference link
In MYSQL a primary key has to be a non-null value ie you will have to indicate by typing in NOT NULL You can re-write the code as follows:
my_id INT([optional]) PRIMARY KEY NOT NULL
When you want to make a Primary Key field it shouldn't be Null.
And
When you use int data type it don't have any (<value>), But number has.
SO
my_Id int not null primary key
I am fairly new to SQL but have been working hard to learn. I am currently stuck on an issue with setting a primary key to have 8 digits no matter what.
I tried using INT(8) but that didn't work. Also AUTO_INCREMENT doesn't work in PostgreSQL but I saw there were a couple of data types that auto increment but I still have the issue of the keys not being long enough.
Basically I want to have numbers represent User IDs, starting at 10000000 and moving up. 00000001 and up would work too, it doesn't matter to me.
I saw an answer that was close to this, but it didn't apply to PostgreSQL unfortunately.
Hopefully my question makes sense, if not I'll try to clarify.
My code (which I am using from a website to try and make my own forum for a practice project) is:
CREATE Table users (
user_id INT(8) NOT NULL AUTO_INCREMENT,
user_name VARCHAR(30) NOT NULL,
user_pass VARCHAR(255) NOT NULL,
user_email VARCHAR(255) NOT NULL,
user_date DATETIME NOT NULL,
user_level INT(8) NOT NULL,
UNIQUE INDEX user_name_unique (user_name),
PRIMARY KEY (user_id)
) TYPE=INNODB;
It doesn't work in PostgreSQL (9.4 Windows x64 version). What do I do?
You are mixing two aspects:
the data type allowing certain values for your PK column
the format you chose for display
AUTO_INCREMENT is a non-standard concept of MySQL, SQL Server uses IDENTITY(1,1), etc.
Use a serial column in Postgres:
CREATE TABLE users (
user_id serial PRIMARY KEY
, ...
)
That's a pseudo-type implemented as integer data type with a column default drawing from an attached SEQUENCE. integer is easily big enough for your case (-2147483648 to +2147483647).
If you really need to enforce numbers with a maximum of 8 decimal digits, add a CHECK constraint:
CONSTRAINT id_max_8_digits CHECK (user_id BETWEEN 0 AND < 99999999)
To display the number in any fashion you desire - 0-padded to 8 digits, for your case, use to_char():
SELECT to_char(user_id, '00000000') AS user_id_8digit
FROM users;
That's very fast. Note that the output is text now, not integer.
SQL Fiddle.
A couple of other things are MySQL-specific in your code:
int(8): use int.
datetime: use timestamp.
TYPE=INNODB: just drop that.
You could make user_id a serial type column and set the seed of this sequence to 10000000.
Why?
int(8) in mysql doesn't actually only store 8 digits, it only displays 8 digits
Postgres supports check constraints. You could use something like this:
create table foo (
bar_id int primary key check ( 9999999 < bar_id and bar_id < 100000000 )
);
If this is for numbering important documents like invoices that shouldn't have gaps, then you shouldn't be using sequences / auto_increment
I have set-up a table using the following SQL script:
CREATE TABLE MY_TABLE (
ID NUMBER NOT NULL,
CODE VARCHAR2(40) NOT NULL,
CONSTRAINT MY_TABLE PRIMARY KEY (ID)
);
CREATE UNIQUE INDEX XUNIQUE_MY_TABLE_CODE ON MY_TABLE (CODE);
The problem is that I need to ensure that CODE does not have a leading zero for its value.
How do I accomplish this in SQL so that a 40-char value without a leading zero is stored?
CODE VARCHAR2 NOT NULL CHECK (VALUE not like '0%')
sorry - slight misread on the original spec
If you can guarantee that all INSERTs and UPDATEs to this table are done through a stored procedure, you could put some code there to check that the data is valid and return an error if not.
P.S. A CHECK CONSTRAINT would be better, except that MySQL doesn't support them.