Short Sql insert Statement? - sql

In MySql I could have a table with an auto increment column and insert that way:
INSERT INTO tbl VALUES(null, "bla", "bla");
Is there any way to do this with Microsoft SQL Server Express?
Instead of this:
INSERT INTO tbl(`v1`, `v2`) VALUES ("bla", "bla");
Thanks

In Sql Server, you do not need to specify a value for identity columns (I'm guessing this is what the null in mysql is doing).
So, the short syntax for inserting into your table would be:
Insert Into tbl Values('bla', 'bla')
This works regardless of whether the column is declared to be the primary key of the table and also works for any position of the column in the table. That is, even if the column is in the middle as shown below:
Create Table tbl (
[Col1] [varchar](50) NULL,
[Id] [int] IDENTITY(1,1) NOT NULL,
[Col2] [varchar](50) NULL
)
Sql Server will still quite happily interpret the insert statement and take care of the identity insert.
As other posters have mentioned, in Sql Server you actually need to issue the Set Identity_Insert tbl On command to be able to specify a value for identity columns.

I think you are asking whether you can include a reference to the identity column in your insert statement and pass a null or some other magic value in the Values or Select clause. No, you cannot. You cannot pass a value for the identity column unless you use SET IDENTITY_INSERT [table] ON and pass an actual value.

INSERT INTO tbl VALUES(null, 'bla', 'bla');
Works; use single quotes.
From http://msdn.microsoft.com/en-us/library/ms174335.aspx
"If the values in the Value list are
not in the same order as the columns
in the table or do not have a value
for each column in the table,
column_list must be used to explicitly
specify the column that stores each
incoming value."

Related

SQL Insert without knowing all of the values for a new row

I have a table with 5 columns and I'd like to insert a new row. The problem is, I do not yet have the values for all 5 columns.
Is it possible to add information to the first and third columns and add the rest later?
This is not referring to a specific database management system. I'd just like to know if it's possible.
Technically, it's not.
However, you can insert dummy values (like NULLs or defaults) into the problem columns and then update them later when you know the correct values.
It depends on your table definition, if column accept null value you don't have to provide a value for it in insert statement.
It depends on table definition.
Some tables require value by design, other not.
It is also worth to mention, that database may be configured to throw error when required fields are not set. In other cases there is only warning and fields are initialized by NULL value despite being defined as "NOT NULL".
Some of fields cannot be omitted at all. Those are mainly primary key fields.
Yes u could do that as follow (MS SQL Server):
CREATE TABLE #TM
([ID] INT IDENTITY(1, 1),
[Col1] INT,
[Col2] VARCHAR(MAX),
[Col3] VARCHAR(MAX),
[Col4] VARCHAR(MAX),
[Col5] VARCHAR(MAX)
);
INSERT INTO #TM
([Col1],
[Col3]
)
SELECT '1',
'2';
Later, you could update the Data in rest of columns with help of ID Column (i.e. unique identity column) which is auto increment.
However, it would insert NULL values in other columns which are not defined in column list.

Can I create a contraint that populates a column on insert regardless of whether data is provided?

A bit of an odd requirement this one.
There is a column on a database (SQL) that is nullable.
I have a constrain in place that populates the column is null/default is provided and it populates from a sequence.
Is it possible to put a constraint in place that ignores any data provided by the insert statement and always puts in the next sequence value?
my current table/constraint is:
CREATE TABLE [dbo].[testmembership](
[id] [int] NOT NULL,
[name] [nvarchar](50) NOT NULL,
[membershipno] [nvarchar](50) NULL
) ON [PRIMARY]
alter table testmembership
add constraint DF_mytblid
default
'PREFIX-'+cast((next value for membershipseq) as nvarchar(50))
for membershipno
If I do the following:
insert into testmembership (id,name,membershipno) values (12,'test',default)
it yeilds the correct sequence generated value.
However, I want it to still have that value from the sequence even if i call this:
insert into testmembership (id,name,membershipno) values (12,'test','ignoreme')
I don't think you can do what you want using a constraint, but you can define a trigger that replaces the normal insert behaviour using the instead of option:
Something like this might work:
create trigger tr on testmembership instead of insert as
insert testmembership (id, name, membershipno)
select id, name, 'PREFIX-' + cast((next value for membershipseq) as nvarchar(50))
from inserted;

Insert into column without having IDENTITY

I have a table
CREATE TABLE [misc]
(
[misc_id] [int] NOT NULL,
[misc_group] [nvarchar](255) NOT NULL,
[misc_desc] [nvarchar](255) NOT NULL
)
where misc_id [int] not null should have been IDENTITY (1,1) but is not and now I'm having issues
With a simple form that insert into this table but since misc_id is looking for a number that a user would not know unless they have access to the database.
I know a option would be to create another column make it IDENTITY(1,1) and copy that data.
Is there another way I will be able to get around this?
INSERT INTO misc (misc_group, misc_desc)
VALUES ('#misc_group#', '#misc_desc#')
I have SQL Server 2012
You should re-create your table with the desired identity column. The following statements will get you close. SQL Server will automatically adjust the table's identity field to MAX(misc_id) + 1 as you're migrating data.
You'll obviously need to stop trying to insert misc_id with new records. You'll want to retrieve the SCOPE_IDENTITY() column after inserting records.
-- Note: I'd recommend having SSMS generate your base create statement so you know you didn't miss anything. You'll have to export the indexes and foreign keys as well. Add them after populating data to improve performance and reduce fragmentation.
CREATE TABLE [misc_new]
(
[misc_id] [int] NOT NULL IDENTITY(1,1),
[misc_group] [nvarchar](255) NOT NULL,
[misc_desc] [nvarchar](255) NOT NULL
-- Todo: Don't forget primary key but can be added later (not recommended).
)
GO
SET IDENTITY_INSERT misc_new ON;
INSERT INTO misc_new
(
[misc_id],
[misc_group],
[misc_desc]
)
SELECT
[misc_id],
[misc_group],
[misc_desc]
FROM misc
ORDER BY misc_id;
SET IDENTITY_INSERT misc_new OFF;
GO
EXEC sp_rename 'misc', 'misc_old';
EXEC sp_rename 'misc_new', 'misc';
GO
If altering the table is not an option, you can try having a different table with the latest [misc_id] value inserted, so whenever you insert a new record into the table, you retrieve this value, add 1, and use it as your new Id. Just don't forget to update the table after.
Changing a int column to an identity can cause problems because by default you cannot insert a value into an identity column without use the set identity_insert command on. So if you have existing code that inserts a value into the identity column it will fail. However its much easier to allow SQL Server to insert values(that is change it to an identity column) so I would change misc_id into an identity column and make sure that there are no programs inserting values into misc_id.
In MSSQL 2012 you can use SEQUENCE objects:
CREATE SEQUENCE [dbo].[TestSequence]
AS [BIGINT]
START WITH 1
INCREMENT BY 1
GO
Change 1 in START WITH 1 with MAX value for [misc_id] + 1.
Usage:
INSERT INTO misc (misc_id, misc_group, misc_desc)
VALUES (NEXT VALUE FOR TestSequence, '#misc_group#','#misc_desc#')

Why is SQL server throwing this error: Cannot insert the value NULL into column 'id'?

I'm using the following query:
INSERT INTO role (name, created) VALUES ('Content Coordinator', GETDATE()), ('Content Viewer', GETDATE())
However, I'm not specifying the primary key (which is id). So my questions is, why is sql server coming back with this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'id', table 'CMT_DEV.dbo.role'; column does not allow nulls. INSERT fails.
The statement has been terminated.
I'm assuming that id is supposed to be an incrementing value.
You need to set this, or else if you have a non-nullable column, with no default value, if you provide no value it will error.
To set up auto-increment in SQL Server Management Studio:
Open your table in Design
Select your column and go to Column Properties
Under Indentity Specification, set (Is Identity)=Yes and Indentity Increment=1
use IDENTITY(1,1) while creating the table
eg
CREATE TABLE SAMPLE(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Status] [smallint] NOT NULL,
CONSTRAINT [PK_SAMPLE] PRIMARY KEY CLUSTERED
(
[Id] ASC
)
)
If the id column has no default value, but has NOT NULL constraint, then you have to provide a value yourself
INSERT INTO dbo.role (id, name, created) VALUES ('something', 'Content Coordinator', GETDATE()), ('Content Viewer', GETDATE())
Encountered the same issue. This is something to do with your table creation. When you created table you have not indicate 'ID' column to be Auto Increment hence you get this error. By making the column Primary Key it cannot be null or contain duplicates hence without Auto Increment pretty obvious to throw column does not allow nulls. INSERT fails.
There are two ways you could fix this issue.
1). via MS SQL Server Management Studio
Got to MS SQL Server Management Studio
Locate your table and right click and select Design
Locate your column and go to Column Properties
Under Indentity Specification: set (Is Identity)=Yes and Indentity
Increment=1
2). via ALTER SQLs
ALTER TABLE table DROP COLUMN id; // drop the existing ID
ALTER TABLE table ADD id int IDENTITY(1, 1) NOT NULL; // add new column ID with auto-increment
ALTER TABLE table ADD CONSTRAINT PK_ident_test PRIMARY KEY CLUSTERED (id); // make it primary key
You either need to specify an ID in the insert, or you need to configure the id column in the database to have Identity Specification = Yes.
As id is PK it MUST be unique and not null.
If you do not mention any field in the fields list for insert it'll be supposed to be null or default value.
Set identity (i.e. autoincrement) for this field if you do not want to set it manualy every time.
You need to set autoincrement property of id column to true when you create the table or you can alter your existing table to do this.
you didn't give a value for id. Try this :
INSERT INTO role (id, name, created) VALUES ('example1','Content Coordinator', GETDATE()), ('example2', 'Content Viewer', GETDATE())
Or you can set the auto increment on id field, if you need the id value added automatically.
I had a similar problem and upon looking into it, it was simply a field in the actual table missing id (id was empty/null) - meaning when you try to make the id field the primary key it will result in error because the table contains a row with null value for the primary key.
This could be the fix if you see a temp table associated with the error. I was using SQL Server Management Studio.
WARNING! Make sure the target table is locked when using this method
(As per #OnurOmer's comment)
if you can't or don't want to set the autoincrement property of the id, you can set value for the id for each row like this:
INSERT INTO role (id, name, created)
SELECT
(select max(id) from role) + ROW_NUMBER() OVER (ORDER BY name)
, name
, created
FROM (
VALUES
('Content Coordinator', GETDATE())
, ('Content Viewer', GETDATE())
) AS x(name, created)
RULE: You cannot IGNORE those colums that do not allow null values, when inserting new data.
Your Case
You're trying to insert values, while ignoring the id column, which does not allow nulls. Obviously this won't work.
Gladly for you the "Identity Specification" seems to automatically fill the not nullable id values for you (see selected answer), when you later execute the insert query.
My Case
The problem (while using SSMS): I was having this error when trying to add a new non-nullable column to an already existing table with data. The error I'd got was:
Cannot insert the value NULL into column 'id_foreign', table 'MyDataBase.dbo.Tmp_ThisTable'; column does not allow nulls. INSERT fails.
The statement has been terminated.
The solution:
I created the column I needed id_foreign, allowing nulls.
I edited/inserted all the required values for id_foreign.
Once the values where in place, I went back and unchecked the "Allow Nulls" checkbox. Now the error was gone.

How do I insert into a table and get back the primary key value?

I have a primary key set up to auto increment.
I am doing multiple queries and I need to retrieve that primary key value to use as a foreign key in another table (IsIdentity = TRUE).
Is there any elegant way to get back the primary key value when I do an insert query? Right now I am requerying and getting the highest value in that column which seems really hacky.
Any suggestions?
If you are using SQL Server 2005 or later, you can use the OUTPUT clause.
create table T(
pk int identity primary key,
dat varchar(20)
);
go
insert into T
output inserted.pk
values ('new item');
go
drop table T;
The output can be directed to a table as well as to the client. For example:
create table T(
pk int identity primary key,
dat varchar(20)
);
create table U(
i int identity(1001,1) primary key,
T_pk int not null,
d datetime
);
go
insert into T
output inserted.pk, getdate()
into U(T_pk,d)
values ('new item'), ('newer item');
go
select * from T;
select * from U;
go
drop table T, U;
Beginning with SQL Server 2008, you can use "composable DML" for more possibilities.
insert into YourTable values (...)
get the new PK with scope_identity()
select scope_identity()
INSERT INTO YourTable (1, 2, etc.)
OUTPUT inserted.yourIDcolumn
VALUES (value1, value2, value...)
Note: This is for MS SQL 2005 and greater
SCOPE_IDENTITY() is probably what you want. It returns the ID of the last record inserted by the same code context in which it executes.
IDENT_CURRENT('tablename') is subject to concurrency issues. That is, there's no guarantee that another record won't be inserted between the INSERT and the call to IDENT_CURRENT.
I must confess, I'm not sure to what source of amazement the VillageIdiot's outburst refers, but I myself am quite astonished that this question does not appear to be a duplicate at all.
holy crap!!!
just call SCOPE_IDENTITY() function:
insert into your_talble(col1,col2) values('blah','more blah')
select scope_identity()
because selecting highest value will return error if any other statement make an insert. the function scope_identity() returns the identity created in current context (that is by your statement)
You should use scope_identity(). And I recommend to wrap insert statement and scope_identity() into transaction.