Author |
Topic |
azmi
Starting Member
37 Posts |
Posted - 2005-12-09 : 22:01:49
|
/*hi guys,I want to add new column (column_new) in between column2 and column3 using sql script. CREATE TABLE test( column1 INT, column2 INT, column3 INT, column4 INT,)GOGRANT ALL ON test TO publicGOSELECT * FROM testGODROP TABLE testGO--ALTER TABLE test ADD colum_new INT--resultcolumn1 column2 column3 column4 colum_new ----------- ----------- ----------- ----------- ----------- /*what i want is like this */column1 column2 column_new column3 column4 ----------- ----------- ----------- ----------- ----------- any idea.. |
|
robvolk
Most Valuable Yak
15732 Posts |
Posted - 2005-12-09 : 22:14:20
|
You have to create a new table with the columns in the order you want, copy the data into it, drop the old table and rename the new table with the old name. ALTER TABLE...ADD can only put columns at the end of the list. |
|
|
azmi
Starting Member
37 Posts |
Posted - 2005-12-09 : 22:27:42
|
Well that what i did previously. That required more time than i thought. Furthermore if i got a lot column in my table and also huge data inside.. |
|
|
Kristen
Test
22859 Posts |
Posted - 2005-12-10 : 00:43:07
|
Why not add the column on the end then? (which won't need a "copy over and rename" of the table - although there are potential issues with the efficiency of the layout of the data in the table if you use that approach).Alternatively, if the data is too big to allow you to mess with it create a separate table with a 1:1 join to the main table.All compromises over "doing it right", but we're in the real world, right? Kristen |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2005-12-10 : 02:25:08
|
You should use Enterprise Manager to know how it scripts the changes. Ordinal Position of the column doesnt matter and you can have it at the place you want in Select statementMadhivananFailing to plan is Planning to fail |
|
|
azmi
Starting Member
37 Posts |
Posted - 2005-12-11 : 20:32:40
|
I thought there is other easiest way to do it. Well definitly i'am wrong. Yes there is no easy way in this real world. Thanks guys for your reply :-). |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-12-12 : 00:09:09
|
There technically is an easy way to do this. It's very wrong though. You can change the colid on the syscolumns table. It's very dangerous though and can really mess some things up. The bottom line is this...if the physical order of the columns is important to your application, something has been designed very wrong. Having said that, here is a test script for you to examine that does the exact change you want. Follow the directions very carefully. When you run the script in Query Analyzer, run it in text results mode. Make sure you run it in pieces.Here is the code:USE NorthwindGOPRINT 'This script attempts to reorder a column by updating the system tables themselves. 'CREATE TABLE crazy_test( identcol INT IDENTITY(1,1), col1 INT, col2 INT, col3 INT, CONSTRAINT pk_crazy_test PRIMARY KEY NONCLUSTERED (identcol ASC))CREATE CLUSTERED INDEX idx_crazy_test ON crazy_test(col2 DESC)INSERT crazy_test(col1, col2, col3) SELECT 1,8,9 UNION ALL SELECT 2,7,11 UNION ALL SELECT 3,6,10 UNION ALL SELECT 4,5,12PRINT 'Order works as expected'SELECT * FROM crazy_testPRINT 'Notice the colorder, which you would think "orders" the table columns.'SELECT so.name AS table_name, sc.name AS column_name, sc.colid, sc.colorderFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'--ONLY RUN THE SCRIPT TO HERE. TAKE TIME TO LOOK AND SEE WHAT YOU HAVE.--Look in enterprise manager to see rows are ordered as expected. Make sure you right-click on the Tables and refresh first.--Now set the server to allow updates directly on the system tables and update the column order.EXEC sp_configure 'show advanced options',1GORECONFIGUREGOEXEC sp_configure 'allow updates',1GORECONFIGURE WITH OVERRIDEGOUPDATE scSET sc.colorder = CASE WHEN sc.colorder = 3 THEN 2 WHEN sc.colorder = 2 THEN 3 ELSE sc.colorder ENDFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'GOPRINT 'Notice the new colorder.'SELECT so.name AS table_name, sc.name AS column_name, sc.colid, sc.colorderFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'GODBCC FREEPROCCACHEPRINT 'Order works the same in Query Analyzer though.'SELECT * FROM crazy_testPRINT 'The indexes are still also on the right columns.'EXEC sp_helpindex 'crazy_test'--ONLY RUN THE SCRIPT TO HERE. TAKE TIME TO LOOK AND SEE WHAT YOU HAVE.--If you check the Enterprise Manager table views and the diagrams, the order also has not changed.----Again, make sure you hit the refresh first in Enterprise Manager before checking.--The indexes also have not been changed.--*****Now, we will change the colid like we did the column order. We'll rerun the test from scratch so it's a fair test.--DO NOT RUN THIS ON A PRODUCTION SYSTEM. THIS IS JUST FOR TESTING.GODROP TABLE crazy_testGO EXEC sp_configure 'allow updates',0GORECONFIGUREGOCREATE TABLE crazy_test( identcol INT IDENTITY(1,1), col1 INT, col2 INT, col3 INT, CONSTRAINT pk_crazy_test PRIMARY KEY NONCLUSTERED (identcol ASC))CREATE CLUSTERED INDEX idx_crazy_test ON crazy_test(col2 DESC)INSERT crazy_test(col1, col2, col3) SELECT 1,8,9 UNION ALL SELECT 2,7,11 UNION ALL SELECT 3,6,10 UNION ALL SELECT 4,5,12PRINT 'Order works as expected'SELECT * FROM crazy_testPRINT 'Notice the colid.'SELECT so.name AS table_name, sc.name AS column_name, sc.colid, sc.colorderFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'--ONLY RUN THE SCRIPT TO HERE. TAKE TIME TO LOOK AND SEE WHAT YOU HAVE.--Look in enterprise manager to see rows are ordered as expected. Make sure you right-click on the Tables and refresh first.--Now set the server to allow updates directly on the system tables and update the column id.EXEC sp_configure 'show advanced options',1GORECONFIGUREGOEXEC sp_configure 'allow updates',1GORECONFIGURE WITH OVERRIDEGOUPDATE scSET sc.colid = CASE WHEN sc.colid = 3 THEN 2 WHEN sc.colid = 2 THEN 3 ELSE sc.colid ENDFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'GOPRINT 'Notice the new colid.'SELECT so.name AS table_name, sc.name AS column_name, sc.colid, sc.colorderFROM sysobjects so INNER JOIN syscolumns sc ON so.id = sc.idWHERE so.name = 'crazy_test'GODBCC FREEPROCCACHEPRINT 'Order is now different in Query Analyzer.'SELECT * FROM crazy_testPRINT 'We messed up the indexes though. Notice, it now shows col1 as the indexed column.'PRINT 'THIS IS WHY THIS SHOULD NEVER BE RAN ON A PRODUCTION SYSTEM. JUST RECREATE THE TABLE IF YOU'PRINT 'NEED A NEW ORDER. ORDER SHOULD NOT BE IMPORTANT IN THE RDMS THOUGH, SO YOU PROBABLY HAVE BAD DESIGN'EXEC sp_helpindex 'crazy_test'--ONLY RUN THE SCRIPT TO HERE. TAKE TIME TO LOOK AND SEE WHAT YOU HAVE.--If you check the Enterprise Manager table views and the diagrams, the order has been changed both in table design and the diagram tool.--Erase the test tables and reset the system to not allow system table updates.GODROP TABLE crazy_testGO EXEC sp_configure 'allow updates',0GORECONFIGUREGO MeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
|
|
azmi
Starting Member
37 Posts |
Posted - 2005-12-12 : 03:10:39
|
I knew there is others way to do it,thanks derrickleggett!, i had try the code.It's work fine and that what i need. As far as RDMS design concerned,i accept your suggestion and i'll take this alternative approach for my general knowledge and for my code reference:-). |
|
|
Kristen
Test
22859 Posts |
Posted - 2005-12-12 : 04:26:47
|
You would do well to start removing all code that depends on column position Right Now! Most especially if it is based on SELECT * rather than SELECT Col1, Col2, ColA, ColB, ...Kristen |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2005-12-12 : 04:39:28
|
quote: Originally posted by Kristen You would do well to start removing all code that depends on column position Right Now! Most especially if it is based on SELECT * rather than SELECT Col1, Col2, ColA, ColB, ...Kristen
Thats exactly I meant alsoOrdinal Position of the column doesnt matter and you can have it at the place you want in Select statementMadhivananFailing to plan is Planning to fail |
|
|
derrickleggett
Pointy Haired Yak DBA
4184 Posts |
Posted - 2005-12-12 : 08:39:36
|
Make anyone who runs that script above is extremely careful. Running that kind of script on a production server could cause support issues with Microsoft. It IS NOT something they support or recommend. It was meant as a test script only. Just because you can do it doesn't mean you should. You could jump off a tall 50 story building without a parachute. Unless you're an IDIOT though, it's probably not a good idea. MeanOldDBAderrickleggett@hotmail.comWhen life gives you a lemon, fire the DBA. |
|
|
azmi
Starting Member
37 Posts |
Posted - 2005-12-12 : 22:30:01
|
Thanks for your all idea.That why i like this forum. Well derrickleggett that's very cool.That we can suggest for future 'fear factor' tv programme :-).By the way this is very good discussion.Have a nice day. |
|
|
eyechart
Master Smack Fu Yak Hacker
3575 Posts |
Posted - 2005-12-12 : 23:27:34
|
Can anyone think of a situation where the column position matters? I thought about this a bit and even tried to write some "bad code" that depended on this and couldn't do it.Azmi, the column position makes no difference whatsoever. If you have code that shows otherwise I would really like to see it.-ec |
|
|
Kristen
Test
22859 Posts |
Posted - 2005-12-13 : 01:58:03
|
SELECT *And then some client logic that does RecordSet(5)Or the columns are arranged as an array - PriceBreak_1, PriceBreak_2 ... PriceBreak_5 and now we need PriceBreak_6 and our client logic does FOR ColumnNumber = 1 TO 5 ...But that sort of programming is nuts!Kristen |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2005-12-13 : 02:09:14
|
I have seen Newbies using rs(0) than rs("Column_Name") which matters if the ordinal position changes. They are good to go if they use Column_Name than ordinal position MadhivananFailing to plan is Planning to fail |
|
|
Kristen
Test
22859 Posts |
Posted - 2005-12-13 : 02:53:08
|
"I have seen Newbies using rs(0) "All the more reason to add the new column on the end, rather than in the middle, eh? Kristen |
|
|
Warazen
Starting Member
3 Posts |
Posted - 2007-09-13 : 16:46:58
|
The Information_Schema.Columns table has an ORDINAL_POSITION field. Is it possible to simply add the desired columns via ALTER TABLE then change the ORDINAL_POSITION for the table in Information_Schema.Columns?I haven't tried this, but it seems the following approach may work. This example assumes there is a table with 2 columns. Basically add the new column, assign it to position 1, then assign the old column to position 2.-- Add the columnIF NOT EXISTS (SELECT * FROM [information_schema].[columns] WHERE table_name = 'TargetTable' AND table_schema = 'dbo' AND column_name = 'TheNewColumn') BEGIN ALTER TABLE [dbo].[TargetTable] ADD TheNewColumn int END-- Move the new column's ordinal position to the top.UPDATE [information_schema].[columns] SET ORDINAL_POSITION = 1WHERE table_name = 'TargetTable' AND table_schema = 'dbo' AND column_name = 'TheNewColumn'-- Move the old column's ordinal position to the bottom.UPDATE [information_schema].[columns] SET ORDINAL_POSITION = 2WHERE table_name = 'TargetTable' AND table_schema = 'dbo' AND column_name = 'TheOldColumn'Some SQL guru is probably screaming right now that this would screw up something at a system level. That's why I'm posting it here. |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2007-09-13 : 17:05:38
|
Never ever attempt to do something like this even if you can once you flip the bit in sp_configure. I doubt it would be allowed anyway since you are attempting to update views.Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/ |
|
|
Warazen
Starting Member
3 Posts |
Posted - 2007-09-13 : 17:09:37
|
Should have done more research before posting that.1. INFORMATION_SCHEMA.Columns is a view to syscolumns.colid.2. Microsoft doesn't support moving ordinal positions in SQL Server.3. Enterprise Manager creates a new table, moves data, and renames the table when you reorder columns.The following thread has the above and additional details.http://community.netscape.com/n/pfx/forum.aspx?nav=printDiscussion&webtag=ws-msdevapps&tid=24163&redirCnt=1 |
|
|
Tsar
Starting Member
1 Post |
Posted - 2007-09-13 : 17:15:08
|
ORDINAL_POSITION is actually a calculated field, and isn't really stored anywhere. For any column, it is the number of columns in that table with colid's not greater than its own colid.I use similar logic all the time to calculate rankings, with the rank of a given record being 1 + the number of higher-valued records. It allows for ties and such with a minimum of code (or thinking, which is always a plus for me).Good luck, and get those ordinal dependencies out of your code ASAP! |
|
|
Warazen
Starting Member
3 Posts |
Posted - 2007-09-13 : 17:19:48
|
Thanks TKizer and Tsar. |
|
|
Next Page
|