2009-10-22 83 views
61

如何使用SQL Server 2005中的SQL查詢更改表中的列順序?如何在sql server 2005中使用sql查詢更改表中的列順序?

我想使用SQL查詢重新排列表中的列順序。

+2

如果您指的是更改表中存在的列的_position_,則需要使用首選順序創建一個新表,然後插入舊錶中的數據,然後刪除原始表。沒有其他方法(據我所知)做到這一點。 – 2009-10-22 05:24:10

+0

您是在談論SELECT語句上的列順序還是表格定義上的列順序? – 2009-10-22 05:24:41

回答

61

你不能。列順序只是我們人類關心的一個「整體」事物 - 對於SQL Server來說,它幾乎總是無關緊要的。

SQL Server Management Studio在更改列順序時會在後臺執行什麼操作,將從頭開始重新創建表,並使用新的CREATE TABLE命令,複製舊錶中的數據,然後刪除它。

沒有用於定義列排序的SQL命令。

+0

MySQL允許您使用'alter table'重新排序默認訂單。我會假設MS SQL Server也可以這樣做。 (此外,我認爲他只是在查詢之後,而不是存儲) – lexu 2009-10-22 05:26:32

+4

不,不存在這樣的事情ni SQL Server - 不應該在任何真正的RBDMS中 - 列順序不是一個與SQL表相關的概念 – 2009-10-22 05:27:05

+35

@marc_s There不支持列順序是一個很好的理由。即使它只是視覺效果。當您創建「SELECT *」時,它可以更容易地查看具有給定列順序的表中的數據。我是一名開發人員,一直都在做這種查詢。您可以利用預定好的列順序節省一些時間。當然,從任何其他角度來看,它都沒有意義:任何事情都不應該依賴於列順序。順便說一句,有一個ORDINAL_POSITION列qhen您查詢「INFORMATION_SCHEMA.COLUMNS」。我不知道這意味着什麼...但它必須與此有關。 – JotaBe 2013-06-21 12:46:36

18

您必須按照您希望返回的順序顯式列出字段,而不是使用*作爲「默認」順序。

原始查詢:

select * from foobar 

回報

foo bar 
--- --- 
    1 2 
現在

select bar, foo from foobar 

bar foo 
--- --- 
    2 1 
-1

使用

SELECT * FROM TABLE1 

它顯示錶的默認列順序。

如果你想改變列的順序。

指定的列名,以顯示相應

SELECT COLUMN1, COLUMN5, COLUMN4, COLUMN3, COULMN2 FROM TABLE1 
11

這是類似的問題在查詢的結果排序記錄..而且通常沒有人喜歡在形式上正確的答案;-)

所以這裏有雲:

  • 爲根據SQL標準,表中的列未被「排序」
  • 因此,select *不會強制以特定順序返回列
  • 通常,每個RDBMS都有一種「默認」順序(通常是那個訂單將列添加到表中,或者在create table' or in the alter table中添加`語句
  • 因此,如果您依賴列的順序(因爲您正在使用查詢的結果來從其位置獲取其他數據結構列),按照您希望的順序顯式列出列。
8

你當然可以改變sql語句中列的順序。但是,如果你想抽象表的物理列順序,你可以創建一個視圖。一世。Ë

CREATE TABLE myTable(
    a int NULL, 
    b varchar(50) NULL, 
    c datetime NULL 
); 


CREATE VIEW vw_myTable 
AS 
SELECT c, a, b 
    FROM myTable; 

select * from myTable; 
a b c 
- - - 

select * from vw_myTable 
c a b 
- - - 
+0

這是否會更改查詢時間? – blindguy 2016-02-26 19:33:07

+0

@blindguy不,它不會改變你的查詢時間 – mevdiven 2016-02-29 13:59:09

4

您可以通過創建一個新的表做,複製所有數據上,刪除舊錶,然後重命名新的來代替舊的。

您也可以在表中添加新列,按列數據複製列,刪除舊列,然後重新命名新列以匹配舊列。下面一個簡單的例子: http://sqlfiddle.com/#!3/67af4/1

CREATE TABLE TestTable (
    Column1 INT, 
    Column2 VARCHAR(255) 
); 
GO 

insert into TestTable values(1, 'Test1'); 
insert into TestTable values(2, 'Test2'); 
GO 

select * from TestTable; 
GO 

ALTER TABLE TestTable ADD Column2_NEW VARCHAR(255); 
ALTER TABLE TestTable ADD Column1_NEW INT; 
GO 

update TestTable 
set Column1_NEW = Column1, 
    Column2_NEW = Column2; 
GO 

ALTER TABLE TestTable DROP COLUMN Column1; 
ALTER TABLE TestTable DROP COLUMN Column2; 
GO 

sp_rename 'TestTable.Column1_NEW', 'Column1', 'COLUMN'; 
GO 
sp_rename 'TestTable.Column2_NEW', 'Column2', 'COLUMN'; 
GO 

select * from TestTable; 
GO 
+1

我寫了一個類似的存儲過程。它使用動態SQL自動完成表重建。 https://caseyplummer.wordpress.com/2013/07/22/sql-procedure-to-rebuild-a-table-using-a-specific-column-order/ – Casey 2015-09-22 19:40:31

12

http://msdn.microsoft.com/en-us/library/aa337556.aspx

這個任務不能使用Transact-SQL語句來執行。

那麼,它可以使用create /複印/ drop /重命名,由komma8.komma1

的回答或者您可以使用SQL Server Management Studio中

  1. 對象資源管理器 ,右鍵單擊要重新排序的列表並單擊設計(修改爲2005 SP1或更早版本)
  2. 選擇要重新排序的列名稱左側的框。 (您可以按住[shift]或 鍵盤上的[ctrl]鍵來選擇多個列。)
  3. 將列拖到表格中的其他位置。

然後點擊保存。此方法實際上會刪除並重新創建表,因此可能會發生一些錯誤。

如果更改跟蹤選項爲數據庫和表啓用,您不應該使用此方法。

如果被禁用,需要表重新創建選項應在工具菜單>選項>設計師要清除的防止保存更改,否則「保存更改不允許」將出現錯誤。

  • 禁用禁止保存需要表重新創建微軟強烈建議選項反對變化,因爲它會導致現有的更改跟蹤信息被刪除,重新創建表時,所以你應該如果啓用更改跟蹤功能,請不要禁用此選項!

在創建主鍵和外鍵時也可能出現問題。

如果發生上述任何錯誤,則保存失敗,這將使您保留原始列順序。

+0

太棒了! ........ – Nezir 2017-01-25 17:14:28

0

在一天結束時,您根本無法在MS SQL中執行此操作。我最近使用從查找表讀取的存儲過程創建了表(應用程序啓動)。當我創建了一個視圖,將這些視圖與另一個我手動創建的較早的視圖(相同的架構和數據)組合在一起的視圖時,它失敗了 - 僅僅因爲我正在使用''Select * UNION Select *'視圖。同時,如果我只使用通過存儲過程創建的那些,我就會成功。

結論:如果有任何應用程序依賴於列的順序,那麼編程確實不是很好,並且肯定會在未來造成問題。列應該'感覺'可以自由地在任何地方並用於任何數據處理(INSERT,UPDATE,SELECT)。

0

你可以選擇是否使用索引..索引完成後,*從XXXX結果應該按照該指數,但只有結果集..不表

的structrue
0

你可以改變這一點使用SQL查詢。這裏是sql查詢來改變列的順序。

ALTER TABLE table name 
CHANGE COLUMN `column1` `column1` INT(11) NOT NULL COMMENT '' AFTER `column2`; 
+0

我不知道這是否會像SSMS一樣丟棄並重新創建表格。無論哪種方式,我都不會在生產數據庫上滾動骰子,儘管這種方法看起來很有趣,值得一些關注。 – samosaris 2015-12-03 21:22:54

+0

此功能在OP中指定的SQL Server中不起作用。希望它做到了。 – Bill 2016-03-11 17:48:44

+0

這是MySQL語法,而不是SQL Server。 – 2017-02-08 15:24:48

0

您可以通過以下步驟實現它:

  1. 刪除所有外鍵和原表的主鍵。

  2. 重命名原始表。

  3. 使用CTAS以您想要的順序創建原始表格。

  4. 放下舊錶。

  5. 適用所有約束回原來的表

1

如果你的表有足夠的列,那麼你可以試試這個。首先用首選的列順序創建一個新表。

create table new as select column1,column2,column3,....columnN from table_name; 

現在用drop命令

drop table table_name; 

現在新建的表重命名爲舊錶名刪除表。

rename new to table_name; 

現在選擇表格,您可以按照以前的方式重新排列您的列。

select * from table_name; 
-1

alter table name修改columnname int(5)first; 會將該列先帶入 alter table name修改columnname int(5)after(tablename);

2

在SQLServer的管理工作室:

工具 - >選項 - >設計 - >表和數據庫設計

  • 取消選擇 '禁止保存需要表重新創建的變化'。

然後:

  • 右鍵單擊要重新排序的列的表。
  • 點擊'設計'。
  • 將列拖到您想要的順序。
  • 最後點擊保存。

SQLServer Management Studio將刪除表並使用該數據重新創建它。

-2

示例:在表狀態中更改field_price後的field_priority的位置。

ALTER TABLE `status` CHANGE `priority` `priority` INT(11) NULL DEFAULT NULL AFTER `price`; 
+1

這是MySQL語法,不是SQL Server。 – 2017-02-08 15:25:04

1

Sql server在內部構建腳本。它創建一個包含新更改的臨時表,並複製數據並刪除當前表,然後從臨時表中重新創建表插入。我從「生成更改腳本」選項ssms 2014中找到它。像這樣的腳本。從Here: How to change column order in a table using sql query

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_emps 
    (
    id int NULL, 
    ename varchar(20) NULL 
    ) ON [PRIMARY] 
GO 
ALTER TABLE dbo.Tmp_emps SET (LOCK_ESCALATION = TABLE) 
GO 
IF EXISTS(SELECT * FROM dbo.emps) 
    EXEC('INSERT INTO dbo.Tmp_emps (id, ename) 
     SELECT id, ename FROM dbo.emps WITH (HOLDLOCK TABLOCKX)') 
GO 
DROP TABLE dbo.emps 
GO 
EXECUTE sp_rename N'dbo.Tmp_emps', N'emps', 'OBJECT' 
GO 
COMMIT 
0

如果要重新排序的列最近已創建爲空,則列可以被刪除,以正確的順序重新添加。

這發生在我身上,手動擴展數據庫以添加新功能,而且我錯過了一列,並且當我添加它時,順序不正確。

在找到沒有適當的解決方案後,我只是使用以下類型的命令更正了表格。

ALTER TABLE tablename DROP COLUMN columnname; 
ALTER TABLE tablename ADD columnname columntype; 

注意:只有在您要刪除的列中沒有數據的情況下才能執行此操作。

人們說列順序無關緊要。我經常使用SQL Server Management Studio「生成腳本」來創建數據庫模式的文本版本。爲了有效地對這些腳本(git)進行版本控制並對它們進行比較(WinMerge),兼容數據庫的輸出是相同的,並且突出顯示的差異是真正的數據庫差異。

列順序無關緊要;但只針對一些人,而不是針對每個人!