Correctly insert row into MS SQL Server - sql

I have a SQL Server table created with:
IF OBJECT_ID('dbo.Messages', 'U') IS NOT NULL
DROP TABLE dbo.Messages
GO
CREATE TABLE dbo.Messages
(
Id INT NOT NULL PRIMARY KEY, -- primary key column
Username [NVARCHAR](50) NOT NULL,
MessageType [NVARCHAR](50) NOT NULL,
Recepient [NVARCHAR](50) NOT NULL,
RecepientType [NVARCHAR](50) NOT NULL,
Payload [NVARCHAR](255),
Stamp DATETIME
);
GO
When I try to insert data into the table, an error happens.
Insert statement:
INSERT INTO dbo.Messages
VALUES ('thin', 'message.broadcast', 'channelID', 'channel', 'test', '2019-07-23 15:19:08.960697828 +0300 EEST m=+14.232534538')
Column name or number of supplied values does not match table
definition.
Is this happening because my datetime needs to formatted for SQL Server, or do I need to describe the primary key differently in to order to have SQL Server autogenerate values for this column?
What would be the correct way to do this?

You are missing ID in your insert statement.
If you want ID to be autogenerated you need to use IDENTITY(1, 1) where you choose seed and increment step in place of 1's.
If you don't want to autogenerate ID, then you need to include it in INSERT statements.
Column definition should be:
Id INT IDENTITY(1, 1) PRIMARY KEY

Consider change stamp column to timestamp and id to identity column like this:
IF OBJECT_ID('dbo.Messages', 'U') IS NOT NULL
DROP TABLE dbo.Messages
GO
CREATE TABLE dbo.Messages
(
Id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, -- primary key column
Username [NVARCHAR](50) NOT NULL,
MessageType [NVARCHAR](50) NOT NULL,
Recepient [NVARCHAR](50) NOT NULL,
RecepientType [NVARCHAR](50) NOT NULL,
Payload [NVARCHAR](255),
Stamp [timestamp] NOT NULL -- timestamp column
);
GO
Then, simply insert your data:
INSERT INTO dbo.Messages
(Username, MessageType, Recepient, RecepientType, Payload)
VALUES('thin', 'message.broadcast', 'channelID', 'channel', 'test')

Although your error clears that 6 values are passing for 7 columns.
You need to insert specifically column names.
Insert into Messages ( Username , MessageType , Recepient , RecepientType , Payload , Stamp )
values ('thin', 'message.broadcast', 'channelID', 'channel', 'test', '2019-07-23 15:19:08.960697828 +0300 EEST m=+14.232534538')
After that also you are facing an issue which is corrected by this.
If Id want to be inserted automatic, then make it idenity like Id int identity(1, 1) not null

You need to add as many columns in your insert statement as there are columns in your table, except for identity fields.
Without your Id as identity, you need this
insert into Messages (Id, Username, MessageType, Recepient, RecepientType, Payload, Stamp)
values (1, 'thin', 'message.broadcast', 'channelID', 'channel', 'test', '2019-07-23 15:19:08.960697828 +0300 EEST m=+14.232534538')
This means its up to you to determine the next value for your Id every time.
Better is to create the Id field as identity like this
Id INT IDENTITY(1, 1) PRIMARY KEY
Now you can simply do this (the Id value will be automatic incremented now)
insert into Messages (Username, MessageType, Recepient, RecepientType, Payload, Stamp)
values ('thin', 'message.broadcast', 'channelID', 'channel', 'test', '2019-07-23 15:19:08.960697828 +0300 EEST m=+14.232534538')
Using column names in your insert also has the benefit that you can put them in any order you like

Related

Constraint not working as desired for my INSERT?

I am creating a Table named "Cliente" with some constraints on it as it follows:
CREATE TABLE public."Cliente" (
"K_CODCLIENTE" numeric(5) NOT NULL,
"N_NOMBRE1" varchar(15) NOT NULL,
"N_NOMBRE2" varchar(15) NOT NULL,
"N_APELLIDO1" varchar(15) NOT NULL,
"N_APELLIDO2" varchar(15),
"N_DIRECCION" varchar(50) NOT NULL,
"Q_TELEFONO" numeric(10) NOT NULL,
"K_CODREF" numeric(5),
"I_TIPOID" varchar(2) NOT NULL,
"Q_IDENTIFICACION" varchar(10) NOT NULL,
CONSTRAINT "PK_Cliente" PRIMARY KEY ("K_CODCLIENTE"),
CONSTRAINT "UQ_ID_TIPOID_CLIENTE" UNIQUE ("I_TIPOID","Q_IDENTIFICACION"),
CONSTRAINT "CK_CODCLIENTE" CHECK ("K_CODCLIENTE" >= 100),
CONSTRAINT "CK_Q_IDENTIFICACION" CHECK ("Q_IDENTIFICACION" IN ('CC', 'PA', 'CE', 'NI', 'OT'))
);
When I try to insert some values on it:
INSERT INTO "Cliente"
VALUES ('101','Juan','Felipe','Ortiz','Rojas','AK 15 no. 28-05','3101125507',null,'CC','51111111');
I get the following error (in PostgreSQL 14, on Fedora):
[23514] ERROR: new row for relation "Cliente" violates check constraint "CK_Q_IDENTIFICACION"
Detail: Failing row contains (101, Juan, Felipe, Ortiz, Rojas, AK 15 no. 28-05, 3101125507, null, CC, 51111111).
I am trying to restrict the "Q_IDENTIFICACION" column so it can only be filled with 'CC', 'PA', 'CE, 'NI' or 'OT'.
Maybe I'm doing something wrong when declaring the constraint "CK_Q_IDENTIFICACION"?
Seems like you messed up the mapping of values and are trying to insert '51111111' to "Q_IDENTIFICACION".
Consider this more revealing variant with a formatted list of target columns:
INSERT INTO "Cliente"
("K_CODCLIENTE", "N_NOMBRE1", "N_NOMBRE2", "N_APELLIDO1", "N_APELLIDO2", "N_DIRECCION" , "Q_TELEFONO", "K_CODREF", "I_TIPOID", "Q_IDENTIFICACION")
VALUES ('101' , 'Juan' ,'Felipe' , 'Ortiz' , 'Rojas' , 'AK 15 no. 28-05', '3101125507', NULL , 'CC' , '51111111'); -- !
Maybe you want to switch the last two column names in the table definition - and (not) adapt the VALUES list in the INSERT accordingly? (varchar(2) vs. varchar(10) seems switched as well.)
For persisted code, it's generally advisable to spell out target columns in an INSERT command in any case.
Asides:
Reconsider all these pesky double-quoted upper case identifiers. See:
Are PostgreSQL column names case-sensitive?
Consider plain type text instead of varchar(n) with strikingly tight character limits. See:
Any downsides of using data type "text" for storing strings?

Why am I getting "Cannot insert the value NULL into column ...." here?

Getting the error
Cannot insert the value NULL into column 'id', table
'master.dbo.Problems'; column does not allow nulls. INSERT fails.
on my table created with
CREATE TABLE Problems (
id INT PRIMARY KEY IDENTITY(1,1) NOT NULL,
prompt_code VARCHAR(5000) NOT NULL,
created DATETIME DEFAULT CURRENT_TIMESTAMP
);
after I try to run the basic command
INSERT INTO Problems (prompt_code) VALUES ( '<span>Blah blah blah</span>' );
What gives?

Autoincrement through IDENTITY in SQL Server 2012 Management Studio

I'm trying to do autoincrement in SQL Server 2012 Management Studio by using identity, but I'm not able to fill in values for incremental column ID. What to fill in insert values?
Part of my code looks like this:
CREATE TABLE G_Members
(
ID int(4) IDENTITY(0001, 1) PRIMARY KEY,
Jméno varchar(20) NOT NULL,
Nick varchar(20) NULL,
Příjmení varchar(20) NOT NULL,
Pohlaví char(1) NOT NULL,
Datum_Narození date NULL
);
INSERT INTO G_Members VALUES
( 'Martin', 'Mates', 'Škorník', 'M', 01-AUG-1978);
INSERT INTO G_Members VALUES
(NEXT VALUE FOR G_Members.ID, 'Ondřej', ' ', 'Panenka', 'M', 29-MAR-1983, );
If you have an Auto Increment Column you cannot insert any data for that column. You have to modify your SQL-Statement in such a way that you specify all other columns and obmit the IDENTITY column. This is achieved as follows:
INSERT INTO G_Members (Jméno,Nick,Příjmení, Pohlaví,Datum_Narození) VALUES ( 'Martin', 'Mates', 'Škorník', 'M', 01-AUG-1978);
SQL Server will insert a new value for the Id column.
Edit:
I suggest you to use nvarchar over varchar because then you will be able to store unicode values. Especially for your language this would be a better choice

Cannot insert the value NULL into column 'id', even though Column has IDENTITY property

CREATE TABLE Type1
(
TypeID TINYINT NOT NULL IDENTITY(1,1),
TypeName VARCHAR(20) NOT NULL,
Speed VARCHAR(10) NOT NULL
CONSTRAINT TypeID_pk PRIMARY KEY (TypeID)
);
CREATE TABLE Splan
(
PlanID TINYINT NOT NULL IDENTITY(1,1),
TypeID TINYINT NOT NULL,
PlanName VARCHAR(20) NOT NULL,
Quota SMALLINT NOT NULL
CONSTRAINT PlanID_pk PRIMARY KEY (PlanID)
CONSTRAINT TypeID_fk FOREIGN KEY (TypeID) REFERENCES Type1(TypeID)
);
INSERT INTO Type1(TypeName, Speed)
VALUES ('Sample type', '10Mbps'),
('Other type', '50Mbps');
^Up until there its fine
and then when I enter the following it returns "Msg 515, Level 16, State 2, Line 8
Cannot insert the value NULL into column 'TypeID' ..... column does not allows. INSERT fails." Statement terminates
INSERT INTO Splan(PlanName, Quota)
VALUES ('Some sample name', '500GB'),
('sample2, '250GB');
I've tried creating the constraints at both column and table level but the second INSERT statement still refused to enter. Double checked via the GUI and 'TypeID' definitely has an IDENTITY property.
I've looked about everywhere and this errors seems to stem from the lack of an IDENTITY property, yet its present in my creation statements and the error still comes up. Tried removing the seed and increment from IDENTITY, still nothing. Also tried inserting the data one row at a time, nothing there either.
P.S If you haven't noticed the actual names have been substituted and other columns rows have been omitted.
Since you created typID as NOT NULL, Sql is complaining that the default value (NULL) is not acceptable.
Try
INSERT INTO Splan(TypeID, PlanName, Quota)
VALUES (1, 'Some sample name', '500GB'),
(2, 'sample2, '250GB');
Where corresponding records with TypeID = 1 and TypeID = 2 are in your Type1 table.
You are creating 2 tables: Type1 which has a primary key TypeId that is auto generated
and SPlan which has a primary key PlanId that is also auto generated and a foreign key TypeId that must be supplied and cannot be null.
As written you must enter 1 or more records into Type1 first, obtain their TypeIds, then enter those TypeIds into new records in SPlan.
Incidentally, using TINYINT for your primary key data types is perfectly legal but probably a really bad idea if this is anything other than homework.
You need to supply a value for TypeID in your second query because you have a foreign key relationship with the Type1 table and because the TypeID column in the Splan table is also declared NOT NULL.
INSERT INTO Splan(TypeID, PlanName, Quota)
VALUES (1, 'Some sample name', '500GB'),
(2, 'sample2, '250GB');
Try inserting both records in a transaction using SCOPE_IDENTITY
begin tran
INSERT INTO Type1(TypeName, Speed)
VALUES ('Sample type', '10Mbps')
DECLARE #id INT = SCOPE_IDENTITY();
INSERT INTO Splan(TypeID, PlanName, Quota)
VALUES (#id, 'Some sample name', '500GB')
commit

Ensuring uniqueness of multiple large URL fields in MS SQL

I have a table with the following definition:
CREATE TABLE url_tracker (
id int not null identity(1, 1),
active bit not null,
install_date int not null,
partner_url nvarchar(512) not null,
local_url nvarchar(512) not null,
public_url nvarchar(512) not null,
primary key(id)
);
And I have a requirement that these three URLs always be unique - any individual URL can appear many times, but the combination of the three must be unique (for a given day).
Initially I thought I could do this:
CREATE UNIQUE INDEX uniques ON url_tracker
(install_date, partner_url, local_url, public_url);
However this gives me back the warning:
Warning! The maximum key length is 900 bytes. The index 'uniques' has maximum
length of 3076 bytes. For some combination of large values, the insert/update
operation will fail.
Digging around I learned about the INCLUDE argument to CREATE INDEX, but according to this question converting the command to use INCLUDE will not enforce uniqueness on the URLs.
CREATE UNIQUE INDEX uniques ON url_tracker (install_date)
INCLUDE (partner_url, local_url, public_url);
How can I enforce uniqueness on several relatively large nvarchar fields?
Resolution
So from the comments and answers and more research I'm concluding I can do this:
CREATE TABLE url_tracker (
id int not null identity(1, 1),
active bit not null,
install_date int not null,
partner_url nvarchar(512) not null,
local_url nvarchar(512) not null,
public_url nvarchar(512) not null,
uniquehash AS HashBytes('SHA1',partner_url+local_url+public_url) PERSISTED,
primary key(id)
);
CREATE UNIQUE INDEX uniques ON url_tracker (install_date,uniquehash);
Thoughts?
I would make a computed column with the hash of the URLs, then make a unique index/constraint on that. Consider making the hash a persisted computed column. It shouldn't have to be recalculated after insertion.
Following the ideas from the conversation in the comments. Assuming that you can change the datatype of the URL to be VARCHAR(900) (or NVARCHAR(450) if you really think you need Unicode URLs) and be happy with the limitation on the length of the URL, this solution could work. This also assumes SQL Server 2008 or better. Please, always specify what version you're working with; sql-server is not specific enough, since solutions can vary greatly depending on the version.
Setup:
USE tempdb;
GO
CREATE TABLE dbo.urls
(
id INT IDENTITY(1,1) PRIMARY KEY,
url VARCHAR(900) NOT NULL UNIQUE
);
CREATE TABLE dbo.url_tracker
(
id INT IDENTITY(1,1) PRIMARY KEY,
active BIT NOT NULL DEFAULT 1,
install_date DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,
partner_url_id INT NOT NULL REFERENCES dbo.urls(id),
local_url_id INT NOT NULL REFERENCES dbo.urls(id),
public_url_id INT NOT NULL REFERENCES dbo.urls(id),
CONSTRAINT unique_urls UNIQUE
(
install_date,partner_url_id, local_url_id, public_url_id
)
);
Insert some URLs:
INSERT dbo.urls(url) VALUES
('http://msn.com/'),
('http://aol.com/'),
('http://yahoo.com/'),
('http://google.com/'),
('http://gmail.com/'),
('http://stackoverflow.com/');
Now let's insert some data:
-- succeeds:
INSERT dbo.url_tracker(partner_url_id, local_url_id, public_url_id)
VALUES (1,2,3), (2,3,4), (3,4,5), (4,5,6);
-- fails:
INSERT dbo.url_tracker(partner_url_id, local_url_id, public_url_id)
VALUES(1,2,3);
GO
/*
Msg 2627, Level 14, State 1, Line 3
Violation of UNIQUE KEY constraint 'unique_urls'. Cannot insert duplicate key
in object 'dbo.url_tracker'. The duplicate key value is (2011-09-15, 1, 2, 3).
The statement has been terminated.
*/
-- succeeds, since it's for a different day:
INSERT dbo.url_tracker(install_date, partner_url_id, local_url_id, public_url_id)
VALUES('2011-09-01',1,2,3);
Cleanup:
DROP TABLE dbo.url_tracker, dbo.urls;
Now, if 900 bytes is not enough, you could change the URL table slightly:
CREATE TABLE dbo.urls
(
id INT IDENTITY(1,1) PRIMARY KEY,
url VARCHAR(2048) NOT NULL,
url_hash AS CONVERT(VARBINARY(32), HASHBYTES('SHA1', url)) PERSISTED,
CONSTRAINT unique_url UNIQUE(url_hash)
);
The rest doesn't have to change. And if you try to insert the same URL twice, you get a similar violation, e.g.
INSERT dbo.urls(url) SELECT 'http://www.google.com/';
GO
INSERT dbo.urls(url) SELECT 'http://www.google.com/';
GO
/*
Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'unique_url'. Cannot insert duplicate key
in object 'dbo.urls'. The duplicate key value is
(0xd111175e022c19f447895ad6b72ff259552d1b38).
The statement has been terminated.
*/