Add new column in sql table - sql-server

I want to insert new column in existing table with 2nd position.
Now i have columns order like
Emp_id, Emp_Name, Address, phoneNo.
I want to add "Gender" in near Emp_Name.
Emp_id, Emp_Name, Gender, Address, phoneNo).
I can't delete this table and create new table.

You can not do this programmatically without creating a new table.
if you are allowed to create and delete tables then:
create a new table:
CREATE TABLE new_table_name
(
column_name1 data_type(size),
column_name2 data_type(size),
...
);
move the data from your main table to the new one then delete the old table.
DROP TABLE my_table
after all rename the new table to the name of which was on your old deleted table.
--alternative:
you can reorder columns in your host application if possible!

Hi you may try the following:
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_TableName
(
Emp_id INT NOT NULL,
Emp_Name VARCHAR(100) NULL,
Gender BIT NULL,
[Address] VARCHAR(100) NULL,
phoneNo int NULL
) ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.Tmp_TableName)
EXEC('INSERT INTO dbo.Tmp_TableName (Emp_id, Emp_Name, [Address],phoneNo)
SELECT Emp_id, Emp_Name, [Address],phoneNo FROM dbo.TableName WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.TableName
GO
EXECUTE sp_rename N'dbo.Tmp_TableName', N'TableName', 'OBJECT'
GO
COMMIT
Make sure to change TableName to your actual table name.
Giannis

You can do it but what for?
SQLFiddle demo
Alter table T ADD Gender varchar(10);
Alter table T ADD Address2 varchar(100),phoneNo2 varchar(100);
update T set Address2=Address,PhoneNo2=PhoneNo;
Alter table T DROP COLUMN Address,PhoneNo;
Alter table T ADD Address varchar(100),phoneNo varchar(100);
update T set Address=Address2,PhoneNo=PhoneNo2;
Alter table T DROP COLUMN Address2,PhoneNo2;

Related

Stored Procedure: Unable to execute after creation

I have created a stored procedure which does four things:
create a table
Alter the created table with a new column
Update the new column based on a condition
Alter table again to drop a column.
I created the stored procedure but cannot execute. I get this error
Column name or number of supplied values does not match table definition'
I have checked all the columns and their datatype to ensure they match so I am at my wit's end as to where it has gone wrong. This is my first time writing a stored procedure, so it may be that my code structure is completely wrong. I have attached a simplified code here showing the basic structure and I am hoping if someone can have a look if the structure is right and shed some light!
Thanks a lot
Michelle
SET ANSI_NULLS ON
GO
CREATE PROCEDURE myStoredProcedure
AS
BEGIN
SET NOCOUNT ON
IF OBJECT_ID('newTable') IS NULL
BEGIN
CREATE TABLE newTable
(
[name] [nvarchar] (256) NOT NULL,
[id] [int] NOT NULL,
[date] [datetime2] (7) NULL
)
END;
TRUNCATE TABLE newTable;
INSERT INTO newTable
SELECT [name], [id], [date]
FROM table1;
ALTER TABLE newTable
ADD [Flag] [nvarchar](2) NULL;
UPDATE newTable
SET [Flag] = 1
WHERE YEAR([date]) = 2020;
ALTER TABLE newTable
DROP COLUMN [date];
END;
As per the Guru's comments above, rather create the table as it should be created originally, then update data in it accordingly with your SP.
I altered your SP to work, however, this is still not the correct way to actually use a SP.
See below altered SP:
SET ANSI_NULLS ON
GO
CREATE PROCEDURE myStoredProcedure
AS
BEGIN
SET NOCOUNT ON
IF OBJECT_ID('newTable') IS NULL
BEGIN
CREATE TABLE newTable
(
[id] int primary key identity,
[name] nvarchar(256) NOT NULL,
[date] datetime2 (7) NULL ,
[Flag] nvarchar(2) NULL
)
END;
INSERT INTO newTable (
[name],
[date]
)
SELECT
[name],
[date]
FROM table1;
UPDATE newTable
SET [Flag] = 1
WHERE YEAR([date]) = 2020;
END;
I removed the code to drop the Date Column as this is ill advised.

Inserting to table having issue - Explicit value must be specified for identity column in table

I'm getting ready to release a stored procedure that gets info from other tables, does a pre-check, then inserts the good data into a (new) table. I'm not used to working with keys and new tables as much, and my insert into this new table I'm creating is having this error message having to do with the insert/key:
Msg 545, Level 16, State 1, Line 131
Explicit value must be specified for identity column in table 'T_1321_PNAnnotationCommitReport' either when IDENTITY_INSERT is set to ON or when a replication user is inserting into a NOT FOR REPLICATION identity column.
BEGIN
...
BEGIN
IF NOT EXISTS (SELECT * FROM sys.tables where name = N'T_1321_PNAnnotationCommitReport')
BEGIN
CREATE TABLE T_1321_PNAnnotationCommitReport (
[id] [INT] IDENTITY(1,1) PRIMARY KEY NOT NULL, --key
[progressnote_id] [INT] NOT NULL,
[form_id] [INT] NOT NULL,
[question_id] [INT],
[question_value] [VARCHAR](max),
[associatedconcept_id] [INT],
[crte_date] [DATETIME] DEFAULT CURRENT_TIMESTAMP,
[create_date] [DATETIME] --SCHED_RPT_DATE
);
print 'test';
END
END --if not exists main table
SET IDENTITY_INSERT T_1321_PNAnnotationCommitReport ON;
...
INSERT INTO dbo.T_1321_PNAnnotationCommitReport--(progressnote_id,form_id,question_id,question_value,associatedconcept_id,crte_date, create_date) **I tried with and without this commented out part and it's the same.
SELECT progressnote_id,
a.form_id,
question_id,
questionvalue,
fq.concept_id,
getdate(),
a.create_date
FROM (
SELECT form_id,
progressnote_id,
R.Q.value('#id', 'varchar(max)') AS questionid,
R.Q.value('#value', 'varchar(max)') AS questionvalue,
create_date
FROM
#tableNotes t
OUTER APPLY t.form_questions.nodes('/RESULT/QUESTIONS/QUESTION') AS R(Q)
WHERE ISNUMERIC(R.Q.value('#id', 'varchar(max)')) <> 0
) a
INNER JOIN [CKOLTP_DEV]..FORM_QUESTION fq ON
fq.form_id = a.form_id AND
fq.question_id = a.questionid
--select * from T_1321_PNAnnotationCommitReport
SET IDENTITY_INSERT T_1321_PNAnnotationCommitReport OFF;
END
Any ideas?
I looked at some comparable inserts we do at work, insert into select and error message, and insert key auto-incremented, and I think I'm doing what they do. Does anyone else see my mistake? Thanks a lot.
To repeat my comment under the question:
The error is literally telling you the problem. You turn change the IDENTITY_INSERT property to ON for the table T_1321_PNAnnotationCommitReport and then omit the column id in your INSERT. If you have enabled IDENTITY_INSERT you need to supply a value to that IDENTITY, just like the error says.
We can easily replicate this problem with the following batches:
CREATE TABLE dbo.MyTable (ID int IDENTITY(1,1),
SomeValue varchar(20));
GO
SET IDENTITY_INSERT dbo.MyTable ON;
--fails
INSERT INTO dbo.MyTable (SomeValue)
VALUES('abc');
GO
If you want the IDENTITY value to be autogenerated, then leave IDENTITY_INSERT set to OFF and omit the column from the INSERT (like above):
SET IDENTITY_INSERT dbo.MyTable OFF; --Shouldn't be needed normally, but we manually changed it before
--works, as IDENTITY_INSERT IS OFF
INSERT INTO dbo.MyTable (SomeValue)
VALUES('abc');
If you do specifically want to define the value for the IDENTITY, then you need to both set IDENTITY_INSERT to ON and provide a value in the INSERT statement:
SET IDENTITY_INSERT dbo.MyTable ON;
--works
INSERT INTO dbo.MyTable (ID,SomeValue)
VALUES(10,'def');
GO
SELECT *
FROM dbo.MyTable;
IDENTITY_INSERT doesn't mean "Get the RDBMS to 'insert' the value" it means that you want to want to tell the RDBMS what value to INSERT. This is covered in the opening sentence of the documentation SET IDENTITY_INSERT (Transact-SQL):
Allows explicit values to be inserted into the identity column of a table.
(Emphasis mine)

Change Auto-Increment, Primary Key field from SMALLINT to INT in SQL Server

What is the best way (low impact/low risk) to change a primary key field from SMALLINT to INT? The field is configured to use "Identity Increment" to auto-increment.
I'm starting with the following SQL:
ALTER TABLE category_types ALTER COLUMN id INT NOT NULL;
However, it generates the following error:
ALTER TABLE ALTER COLUMN id failed because one or more objects access this column.
What else is required? Do I need to drop the keys then recreate them? Will this impact the auto-incrementation?
Note: the table doesn't have too many rows, so the performance of the solution is not critical.
I realise this is an old post, but just in case someone stumbles on it: jciberta gave an answer with a slight error. it should read:
-- Change from smallint to int
SET IDENTITY_INSERT category_types ON
ALTER TABLE category_types DROP CONSTRAINT CategoryTypes
ALTER TABLE category_types ALTER COLUMN id INT
ALTER TABLE category_types ADD CONSTRAINT CategoryTypesPK PRIMARY KEY (id)
SET IDENTITY_INSERT category_types OFF
This is output from sql server management studio but should be of some help. It involves creating a temporary table and then copying existing data to the new table. Dropping the original table and renaming the temp table. If the table was empty, it wouldn't do this and could just modify the original table. SET IDENTITY_INSERT [table] ON/OFF allows you to set the identity column when inserting.
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_category_types
(
id int NOT NULL IDENTITY (1, 1),
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_category_types SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_category_types ON
GO
IF EXISTS(SELECT * FROM dbo.category_types)
EXEC('INSERT INTO dbo.Tmp_category_types (id, x)
SELECT CONVERT(int, id), x FROM dbo.category_types WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_category_types OFF
GO
DROP TABLE dbo.category_types
GO
EXECUTE sp_rename N'dbo.Tmp_category_types', N'category_types', 'OBJECT'
GO
ALTER TABLE dbo.category_types ADD CONSTRAINT
PK_category_types PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
Besides setting IDENTITY_INSERT to off, you have to unlink relationships (primary key, foreign keys) before changing data types. Afterwards you have to link them again.
For instance:
-- Change from smallint to int
SET IDENTITY_INSERT category_types OFF
alter table category_types drop CONSTRAINT CategoryTypesPK
alter table category_types alter column id int
alter table category_types add CONSTRAINT CategoryTypesPK PRIMARY KEY (id)
SET IDENTITY_INSERT category_types ON

Populate CreatedOn, ModifiedOn columns

I am building a WCF service with a SQL Server, which will be consumed by a WPF app. I want my database tables to have columns like:
CreatedOn, CreatedBy, LastModifiedOn, LastModifiedBy
Is there a way to create these authomatically, or if not I can create them, but is it possible somehow their values to be populated by SQL server?
Thanks
Made a couple of assumptions here - that CreatedBy/ModifiedBy would be populated with a system variable such as SUSER_SNAME() and that modified values should reflect the same values as created, initially. Assuming this base table:
USE tempdb;
GO
CREATE TABLE dbo.foo(fooID INT PRIMARY KEY);
GO
Make these modifications:
ALTER TABLE dbo.foo ADD CreatedOn SMALLDATETIME
NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE dbo.foo ADD CreatedBy NVARCHAR(32)
NOT NULL DEFAULT SUSER_SNAME();
ALTER TABLE dbo.foo ADD ModifiedOn SMALLDATETIME
NOT NULL DEFAULT CURRENT_TIMESTAMP;
ALTER TABLE dbo.foo ADD ModifiedBy NVARCHAR(32)
NOT NULL DEFAULT SUSER_SNAME();
GO
Now you just need a trigger to handle subsequent updates:
CREATE TRIGGER dbo.foo_audit
ON dbo.foo
FOR UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF EXISTS (SELECT 1 FROM deleted)
BEGIN
UPDATE f
SET ModifiedOn = CURRENT_TIMESTAMP,
ModifiedBy = SUSER_SNAME()
FROM dbo.foo AS f
INNER JOIN inserted AS i
ON f.fooID = d.fooID;
END
END
GO
If you need the username to be passed in from the app, then WCF is going to have to help with that.

Query in SQL2000

How to drop a Particular column in a Table?
CREATE TABLE dbo.MyTable (column_a INT, column_b VARCHAR(20) NULL);
GO
ALTER TABLE dbo.MyTable DROP COLUMN column_b;
GO
EXEC sp_help MyTable;
GO
DROP TABLE dbo.MyTable;
GO

Resources