Add a new table column to specific ordinal position in Microsoft SQL Server

南楼画角 提交于 2019-11-26 08:26:55

问题


Is it possible to add a column to a table at a specific ordinal position in Microsoft SQL Server?

For instance, our tables always have CreatedOn, CreatedBy, LastModifiedOn, LastModifiedBy columns at the \"end\" of each table definition? I\'d like the new column to show up in SSMS above these columns.

If I am scripting all my database changes, is there a way to preserve this order at the end of the table?

FYI, I\'m not trying to institute a flame war on if this should even be done. If you want to read about a thread that degenerates quickly into that, here\'s a good one:

http://www.developersdex.com/sql/message.asp?p=581&r=5014513


回答1:


You have to create a temp table that mirrors the original table's schema but with the column order that you want, then copy the contents of the original to temp. Delete the original and rename the temp.

This is what SQL Management Studio does behind the scenes.

With a schema sync tool, you can generate these scripts automatically.




回答2:


go into SQL Server management Studio, and "design" an existing table. Insert a column in the middle, right click in an empty area and select Generate Change Script...

Now look at the script it creates. it will basically create a temp table with the proper column order, insert the data from the original table, drop the original table, and rename the temp table. This is probably what you'll need to do.

You may also need to uncheck this option to allow creation of change scripts




回答3:


The answer is yes, it is technically possible, but you will have a headache doing so and it will take a long time to execute and set up.

One: Create/Copy/Drop/Rename

This is actually what SQL Server is doing in the graphical interface: here's an example of the script it is generating and executing when you click the 'save' button after adding a new column to the beginning of a table.

/* 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_SomeTable
    (
    MyNewColumn int NOT NULL,
    OriginalIntColumn int NULL,
    OriginalVarcharColumn varchar(100) NULL
    )  ON [PRIMARY]
     TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SomeTable SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable ON
GO
IF EXISTS(SELECT * FROM dbo.SomeTable)
     EXEC('INSERT INTO dbo.Tmp_SomeTable (OriginalIntColumn, OriginalVarcharColumn FROM dbo.SomeTable WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable OFF
GO
DROP TABLE dbo.SomeTable
GO
EXECUTE sp_rename N'dbo.Tmp_SomeTable', N'SomeTable', 'OBJECT' 
GO

GO
COMMIT

Two: ADD COLUMN / UPDATE / DROP COLUMN / RENAME

This method basically involves creating a copy of any existing columns that you want to add to the 'right' of your new column, transferring the data to the new column, then dropping the originals and renaming the new ones. This will play havoc with any indexes or constraints you have, since you have to repoint them. It's technically possible, but again time-consuming both in terms of development and execution.

CREATE TABLE MyTest (a int, b int, d int, e int)

INSERT INTO MyTest (a,b,d,e) VALUES(1,2,4,5)

SELECT * FROM MyTest -- your current table

ALTER TABLE MyTest ADD c int -- add a new column
ALTER TABLE MyTest ADD d_new int -- create copies of the existing columns you want to move
ALTER TABLE MyTest ADD e_new int

UPDATE MyTest SET d_new = d, e_new = e -- transfer data to the new columns

ALTER TABLE MyTest DROP COLUMN d -- remove the originals
ALTER TABLE MyTest DROP COLUMN e

EXEC SP_RENAME 'MyTest.d_new', 'd'; -- rename the new columns
EXEC SP_RENAME 'MyTest.e_new', 'e';

SELECT * FROM MyTest 

DROP TABLE MyTest -- clean up the sample

Three: Live with it

This mightily offends my sense of order ... but sometimes, it just isn't worth reshuffling.




回答4:


To my knowledge there is no known method to change the order of the column. Behind the scenes SQL Management Studio does what Jose Basilio said. And if you have a big table then it is impractical to change the column orders like this way.

You can use a "view". With SQL views you can use any order you like without getting affected by the table column changes.




回答5:


TFS 2013 will do this for you automatically.

Add the new column(s) to your table anyway you like, and then commit your changes to TFS. From there you can open the table's sql file in Visual Studio and manually move the order of the columns in the T-SQL CREATE script. Then you can update your target database by using VS's schema compare tool found under Tools > SQL Server > New Schema Comparison. Choose your Database project with your change as the source, and the database you want to update as the target. Compare, select the table's script, and Update. VS will drop and add automatically. All your data will be safe, and indexes too.




回答6:


Dirty and simple.
Export table to csv.
Insert new data at desired position.
Drop table.
Create new table with desired column specifications.
Load columns from csv to new table.




回答7:


What i think is simple is to add the column ALTER TABLE table1 ADD .. and then create a tmp table like tmp_table1 from the select like SELECT col1,col2,col5,col3,col4 into tmp_table1 from table1; and then drop table1 and rename the tmp_table1 to table1, that is it. I hope it will help someone




回答8:


I am not sure if the thread is still active. I was having the same query with MySQL database. Right clicking the table and selecting 'ALTER' auto generated the below code. Sample provided from sakila db and it worked. Just find out the column after which you want to place your new column and use 'AFTER' keyword

ALTER TABLE `sakila`.`actor` 
CHANGE COLUMN `middle_name` `middle_name` VARCHAR(50) NULL DEFAULT NULL AFTER `first_name`; 



回答9:


Select all the columns into a temp table, and create a new table with the new column you want. Then drop the old table, select all the columns from the temp table, and insert them into the new table with the reordered column. No data is lost.

SELECT * FROM TEMP
SELECT * FROM originaltbl
SELECT * FROM #Stagintbl

DECLARE @ColumnName nvarchar(max);
SET @ColumnName=(SELECT
    DISTINCT STUFF((
        SELECT ',' + a.COLUMN_NAME
        FROM (
            SELECT Column_name 
            FROM INFORMATION_SCHEMA.COLUMNS 
            WHERE TABLE_NAME='originaltbl') a
        for xml path('')
    ),1,1,'') AS ColumnName)

DECLARE @Sqlquery nvarchar(max)
SET @Sqlquery = 'SELECT ' + @ColumnName + ' FROM #Stagintbl' + '';
INSERT INTO originaltbl
EXECUTE(@Sqlquery)


来源:https://stackoverflow.com/questions/769828/add-a-new-table-column-to-specific-ordinal-position-in-microsoft-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!