SQL Server Computed Column Error With Multiple Inserts [closed] - sql-server

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
I have a table in SQL Server 2008 - let's call the table MyTable. The table has a column named Status, which is not a computed column, and is defined as varchar(40) and it allows NULLs; however, there is also a DEFAULT CONSTRAINT on this column, with the default value = 'POOL'. I just added a computed column to the table, using the following:
ALTER TABLE MyTable
ADD PrimaryStatus AS
CASE
WHEN Status LIKE '%/%' THEN LEFT(Status,CHARINDEX('/', Status) - 1)
ELSE Status
END PERSISTED
If I insert records into the table one by one (and let Status default to 'POOL' using the constraint) it works just fine; for instance, this SQL statement has no problem:
INSERT INTO MyTable (Name) VALUES ('Foo')
With the above SQL, I end up with a new record in the table with Name = 'Foo' and Status = 'POOL' and PrimaryStatus = 'POOL'
But if I execute a multi-row INSERT like the following:
INSERT INTO MyTable (Name) VALUES ('Foo'),('Bar')
then it throws an error:
Msg 537, Level 16, State 2, Line 1
Invalid length parameter passed to the LEFT or SUBSTRING function.
If I drop either the default constraint or the computed column (or both), the multi-row INSERT works fine; but for some reason having both the constraint and the computed column are causing the multi-row INSERT to fail. I have tried tweaking the computed column in a variety of ways to account for NULLs (even though I don't think it should matter given the order of evaluation), but nothing seems to remedy the problem.
Anybody ever seen something like this before?

I tried to replicate the error. But, I don't get any error. I could have added this as a comment, but don't have enough points yet. Anyway, this is what i did -
CREATE TABLE [dbo].[MyTable](
[Name] [varchar](50) NULL,
[Status] [varchar](50) NULL
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [DF_MyTable_Status]
DEFAULT ('POOL') FOR [Status]
GO
Then i removed an extra ) in your code and did -
ALTER TABLE MyTable ADD PrimaryStatus AS
CASE WHEN Status LIKE '%/%' THEN LEFT(Status,CHARINDEX('/',Status)-1)
ELSE Status END PERSISTED
Followed by -
INSERT INTO MyTable (Name) VALUES ('Foo')
INSERT INTO MyTable (Name) VALUES ('Foo'),('Bar')
It works. Am I missing something ?

Related

Error while creating database table with auto increment [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
I want to make auto increment here with the table creation but it gives an error. The database is an oracle database. The SQL is shown below.
CREATE TABLE Continents
(
ConId INT GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) PRIMARY KEY,
Continent VARCHAR(25),
);
Just remove this part
(START WITH 1, INCREMENT BY 1)
Use this syntax.
CREATE TABLE Continents
(
ConId INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
Continent VARCHAR(25),
);
The value of ConId will start at 1 (one) and always increment by one.
Refer to this db<>fiddle
Also refer to Oracle documentation1
The following statement creates a table t1 with an identity column id. The sequence generator will always assign increasing integer values to id, starting with 1.
CREATE TABLE t1 (id NUMBER GENERATED AS IDENTITY);
1SQL Language Reference (Oracle 21c) - CREATE TABLE

How can I write insert command correctly in SQL Server? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I am trying to write some SQL code. I have a table and I want to add values to that table Tasks, but I am getting an error
Invalid Column Name "Manager"
over Task_Name. I identified Id as auto-incrementing with IDENTITY(1,1) and I have a BIT type value as default 0.
How should I write the expression of insert into?
Here is the code for creating:
CREATE TABLE Tasks
(
ID INTEGER IDENTITY(1,1) NOT NULL PRIMARY KEY,
Task_Name VARCHAR(100),
Situation BIT DEFAULT 0
);
Here is the code for Insert Into:
INSERT INTO (ID, Task_Name, Situation)
VALUES (1, "Manager");
INSERT INTO Tasks (Task_Name) values ('Manager')
Don’t specify ID unless turning identity_insert on (column is marked as identity column)
Don’t include column names to insert default values
Use ' to quote strings
INSERT INTO Tasks (Task_Name, Situation) VALUES ('Task_NameValue', 1);

Is NULL necessary?

Is NULL or NOT NULL necessary for Adding a column in SQL Server? (If you are going to run UPDATE statement after)
I tested without it locally, and it seems to work fine both in SQL and on the website; but I wanted to make sure before running release/production.
I looked up some other articles, including microsoft website. Some show it with, some without. SO articles say some benefits of NULL, like if you have information that may be added later. But assuming I am going to run UPDATE to add values after, will it matter?
I am guessing it does not matter from what I've tested and read.
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
UPDATE [dbo].[MyTable] SET NewColumn ='Math' WHERE ID = 1
UPDATE [dbo].[MyTable] SET NewColumn ='Science' WHERE ID = 2
You can skip it, and by default the column will be created as NULL. However it is more legible if you indicate it explicitly.
Keep in mind that if your table already has data, you CANNOT add the column as NOT NULL. For this, you should firstly add the column as NULL, then UPDATE the values with non-null valid data and then alter column to NOT NULL.
Edit: Assuming the default behavior of the sql server when adding columns.
You don't have to write it, when you skip it column will be created as 'NULL'.
Following statements are equal:
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150);
ALTER TABLE [dbo].[MyTable] ADD NewColumn varchar(150) NULL;
If you want to add a column and DB engine should guarantee you that this new column will be always populated you can add a NOT NULL column with a default value.
Other option will be to change the column to NOT NULL after the update.
I'd make sure you have something declarative. And if you are setting as "not null," be sure you have a default value or use can suffer LOTS of data loss if data previously exists. It makes me nervous because this an ALTER vs a CREATE.

Disabled Identify Specification in SQL Server Management Studio [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I tried to create a table which has got 2 primary key and both of them supposed to be auto incremental by changing the Identity specification but in the property window the option (I just mentioned) is disable and I cannot change that.
The column I want to change to auto increment is the primary key of the table and type of it is INT.
What's wrong ? or What I'm wrong ?
As mentioned by TT, you can only have a single identity column and only a single primary key in a table.
For SQL Server 2012 and above, You can however use a SEQUENCE if you need 2 or more auto increment columns. You can then create a PRIMARY KEY on IDENTITY column and a UNIQUE constraint on the column with sequence as default
CREATE SEQUENCE mainseq START WITH 1 INCREMENT BY 1 ;
GO
create table table1 (
id1 int IDENTITY(1,1) NOT NULL PRIMARY KEY,
id2 bigint not null constraint DF_table1_id2 default next value for mainseq,
data varchar(20) not null
)
GO
INSERT INTO table1(data) VALUES('row 1');
INSERT INTO table1(data) VALUES('row 2');
SELECT * FROM table1;
Note that the column with sequence default behaves in differently than an identity. you cannot directly insert into an identity column (except when identity_insert is on) however you can manually insert / update the column being defaulted by a sequence.
From the definition of IDENTITY in SQL Server, you can read that a table can only have one IDENTITY column. See remarks, quote:
Only one identity column can be created per table.
I also wonder how you get two primary keys on a table, as that is not possible. See the following article on creating primary keys, quote from Limitations and Restrictions:
A table can contain only one PRIMARY KEY constraint.
If you need an additional auto incrementing column you could add a trigger to the table FOR INSERT. Something that would find the current maximum value and then add one to it.

SQL Server error: Incorrect syntax near 'MODIFY'. in my query [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
This is the query that I am trying to execute
use [warz]
go
ALTER TABLE dbo.items_lootdata
MODIFY TABLE [RecordID] [int] IDENTITY(1,1) NOT NULL
go
I got the error:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'MODIFY'.
Any ideas?
Add a new column:
use [warz]
go
ALTER TABLE dbo.items_lootdata
ADD [RecordID] [int] IDENTITY(1,1) NOT NULL
go
Modify an existing column:
use [warz]
go
-- remember you cannot alter an existing column to
-- identity, following is only for syntax
ALTER TABLE dbo.items_lootdata
ALTER COLUMN [RecordID] [int] IDENTITY(1,1) NOT NULL
go
One thing to note is that altering an existing column and that too in an Identity is rather tricky.
Edit 1: Commenting the ALTER syntax to correctly highlight the issue as pointed out by marc_s
Relevant solution can be found at this answer.
Looks like your MODIFY TABLE should probably be ALTER COLUMN instead.
IDENTITY can be a pain, as you're not going to have much luck adding it as a property to a column. Tables with IDENTITY columns need to have them ( the IDENTITY columns, that is ) created that way and afterwards it is not easy to get rid of that property either.
Assuming you have a table that is more or less like this:
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'items_lootdata'
AND type = 'U' )
BEGIN
CREATE TABLE dbo.items_lootdata
(
RecordID INTEGER NOT NULL,
MoreData BIT
);
END;
GO
If you want the RecordID to be an IDENTITY enabled column, if your table is currently empty you can simply recreate the object:
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'items_lootdata'
AND type = 'U' )
BEGIN
CREATE TABLE dbo.items_lootdata
(
RecordID INTEGER IDENTITY( 1, 1 ) NOT NULL,
MoreData BIT
);
END;
GO
I prefer to perform a meta-data switch if possible, however, as it would also preserve any data currently contained in your table. This involves a rename, the creation of a new table and the switch itself. You will probably also want to set the first parameter of your IDENTITY column to something greater than or equal to the current maximum value of RecordID as well, as I assume you'll be wanting to put a primary key on that column afterwards.
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'items_lootdata'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.items_lootdata;
CREATE TABLE dbo.items_lootdata
(
RecordID INTEGER NOT NULL,
MoreData BIT
);
INSERT INTO dbo.items_lootdata( RecordID, MoreData )
VALUES( 1, 1 );
END;
GO
EXECUTE dbo.sp_rename #objname = 'dbo.items_lootdata', #newname = 'items_lootdata_old'
IF NOT EXISTS ( SELECT 1
FROM sys.objects
WHERE name = 'items_lootdata'
AND type = 'U' )
BEGIN
--DROP TABLE dbo.items_lootdata;
CREATE TABLE dbo.items_lootdata
(
RecordID INTEGER IDENTITY( 1, 1 ) NOT NULL,
MoreData BIT
);
END;
GO
ALTER TABLE dbo.items_lootdata_old
SWITCH TO dbo.items_lootdata;
GO
DROP TABLE dbo.items_lootdata_old;
GO
INSERT INTO dbo.items_lootdata ( MoreData )
VALUES ( 0 );
GO
SELECT *
FROM dbo.items_lootdata;
Note that for the ALTER ... SWITCH to work, you may have to modify the things you actually can sync before trying it. The SWITCH will fail if the structures aren't otherwise identical ( ie: the original RecordID column is nullable ), so those things will need to be addressed.

Resources