วิธีการเปลี่ยนประเภทข้อมูลคอลัมน์ในฐานข้อมูล SQL โดยไม่สูญเสียข้อมูล


198

ฉันมีฐานข้อมูล SQL Server และฉันก็รู้ว่าฉันสามารถเปลี่ยนชนิดของหนึ่งในคอลัมน์ที่จากไปintbool

ฉันจะทำเช่นนั้นได้อย่างไรโดยไม่สูญเสียข้อมูลที่ป้อนไว้ในตารางนั้นไปแล้ว


3
คุณลองสร้างคอลัมน์บิตใหม่แล้วคัดลอกค่าจากคอลัมน์เก่าไปยังคอลัมน์ใหม่ลบคอลัมน์เก่าและเปลี่ยนชื่อใหม่หรือไม่ ทั้งหมดนี้ในการทำธุรกรรมของหลักสูตรเพื่อย้อนกลับไปที่ปัญหา
Radu Caprescu

2
คุณพูดว่า "ฉันเพิ่งรู้ว่าฉันสามารถเปลี่ยนประเภทจากหนึ่งในคอลัมน์จาก int เป็นบูล" ไม่มีประเภทข้อมูลบูลีน มีบิตแม้ว่า คุณกำลังถามว่าคุณจะทำสิ่งนี้ได้อย่างไร (ตามที่ 2 คำตอบเพื่อให้ครอบคลุม) หรือเป็นคำถามของคุณ "ฉันเพิ่งรู้ว่าเป็นไปได้ - SQL Serverจะทำเช่นนี้ได้อย่างไร"
Martin Smith

คำตอบ:


329

คุณสามารถทำได้โดยใช้คำสั่งต่อไปนี้ ค่าใด ๆ ของ 0 จะกลายเป็น 0 (BIT = false) สิ่งอื่น ๆ จะกลายเป็น 1 (BIT = true)

ALTER TABLE dbo.YourTable
   ALTER COLUMN YourColumnName BIT

ตัวเลือกอื่นคือสร้างคอลัมน์ประเภทBITใหม่กรอกจากคอลัมน์เก่าและเมื่อเสร็จแล้วให้วางคอลัมน์เก่าแล้วเปลี่ยนชื่อใหม่เป็นชื่อเก่า ด้วยวิธีนี้หากบางสิ่งในระหว่างการแปลงผิดพลาดคุณสามารถย้อนกลับได้ตลอดเวลาเนื่องจากคุณยังมีข้อมูลทั้งหมด ..


10
ในคำอื่น ๆ : NULLซากNULL, 0กลายเป็นFalse, ที่ไม่ใช่ค่าเป็นศูนย์ (1, -1 ปี 1999 -987 ... ) Trueกลายเป็น
ÁlvaroGonzález

2
และไม่เคยทำการเปลี่ยนแปลงเช่นนี้จาก GUI ทำให้ผ่านสคริปต์เช่นนี้เสมอ GUI จะดรอปและสร้างตารางใหม่และใช้เวลานานกว่านั้นมาก หากตารางมีขนาดใหญ่และในการผลิตอาจเป็นหายนะ รวมการเปลี่ยนแปลงตารางทั้งหมดควรมีสคริปต์ที่อยู่ในการควบคุมแหล่งเช่นรหัสอื่น ๆ ทั้งหมด
HLGEM

1
ฉันจะเพิ่มแน่ใจว่าคุณมีการสำรองข้อมูลปัจจุบันของฐานข้อมูลก่อนที่จะทำการเปลี่ยนแปลงโครงสร้างใด ๆ ในตารางที่มีข้อมูล และอย่าเรียกใช้การเปลี่ยนแปลงเช่นนี้กับการผลิตในช่วงเวลาที่มีการใช้งานมากที่สุดหากตารางนั้นถูกใช้บ่อยหรือมีขนาดใหญ่
HLGEM

ฉันอนุมัติการแก้ไขโดยไม่ตั้งใจ ... ต้องปฏิเสธ .. เพราะไม่มีการปรับปรุงที่นั่น ... คำตอบนั้นน่ารำคาญ
Vikash Pathak

22
ALTER TABLE tablename
ALTER COLUMN columnname columndatatype(size)

หมายเหตุ: หากมีขนาดคอลัมน์ให้เขียนขนาดด้วย


20

หากเป็นการเปลี่ยนแปลงที่ถูกต้อง

คุณสามารถเปลี่ยนคุณสมบัติ

เครื่องมือ -> ตัวเลือก -> นักออกแบบ -> นักออกแบบตารางและฐานข้อมูล -> ยกเลิกการเลือก -> ป้องกันการบันทึกการเปลี่ยนแปลงที่จำเป็นในการสร้างตารางใหม่

ตอนนี้คุณสามารถเปลี่ยนชื่อคอลัมน์ได้อย่างง่ายดายโดยไม่ต้องสร้างตารางใหม่หรือสูญเสียระเบียน ur


5
คุณไม่ควรทำการเปลี่ยนแปลงตารางโดยใช้ GUI มันจะสร้างตารางใหม่อย่างสมบูรณ์แทนที่จะใช้ตาราง Alter และจะทำให้เกิดปัญหาหากคุณไม่เลือกตัวเลือกนี้และตารางมีขนาดใหญ่ นอกจากนี้คุณควรมีการเปลี่ยนแปลงทั้งหมดในตารางในสคริปต์ในการควบคุมแหล่งที่มา
HLGEM

ดูตัวเลือกนั้นอย่างละเอียด - ปิดความปลอดภัยที่จะป้องกัน GUI ไม่ให้วางตาราง คุณจะไม่ปรากฏข้อมูลการสูญเสียเพราะ GUI จะสร้างตาราง แต่บนเซิร์ฟเวอร์มันจะคัดลอก / ลดลง ดังนั้นหากมีข้อมูลจำนวนมากในตารางจะทำให้การดำเนินการมีขนาดใหญ่มาก นอกจากนี้ฉันคิดว่า (ไม่ใช่บวก) ที่เกิดขึ้นในการทำธุรกรรมเดียวดังนั้นคุณสามารถกรอกบันทึกการทำธุรกรรมของคุณ
JMarsch

1
ฉันเดาว่าฉันต้องการเพิ่มความกระจ่างเล็กน้อยในความคิดเห็นก่อนหน้าของฉัน หากคุณเพียงแค่ทำสิ่งนี้บนเครื่องพัฒนาของคุณคุณอาจจะสบายดี แต่ฉันจะไม่แนะนำให้ใช้วิธีนี้ในฐานข้อมูลการผลิต - โดยเฉพาะถ้ามันเป็นภารกิจที่สำคัญอย่างยิ่ง
JMarsch

8

ทำไมคุณคิดว่าคุณจะสูญเสียข้อมูล เพียงเข้าไปที่ Management Studio แล้วเปลี่ยนประเภทข้อมูล หากค่าที่มีอยู่สามารถแปลงเป็นบูล (บิต) ก็จะทำเช่นนั้น กล่าวอีกนัยหนึ่งถ้าแผนที่ "1" เป็นจริงและ "0" แผนที่เป็นเท็จในเขตข้อมูลเดิมของคุณคุณจะไม่เป็นไร


1
หากคุณมีข้อมูลในตารางสิ่งนี้จะไม่ทำงาน เมื่อคุณพยายามที่จะเปลี่ยนประเภทคอลัมน์ SMS อ้างว่าจำเป็นต้องวางตารางก่อน ... ซึ่งแน่นอนว่าไม่ถูกต้องเนื่องจากคำสั่ง ALTER TABLE ... ALTER COLUMN ทำงานได้ดีแม้ในเขตข้อมูล NULL ที่ไม่ใช่ นี่คือเหตุผลที่พวกเขาคิดว่าพวกเขาสามารถสูญเสียข้อมูล
Tony O'Hagan

1
@ TonyO'Hagan นั่นไม่จริง คุณสามารถปิดคำเตือนและมันจะทำงานได้ดีกับข้อมูลที่มีอยู่ ดูstackoverflow.com/questions/2947865/
Philippe Leybaert

1
โอเคดี! ไม่ทราบว่า เพิ่งลองโหวตคุณ (ย้อนกลับ) แต่ SO กำลังขัดขวางฉันจนกว่าคุณจะแก้ไขคำตอบของคุณ อาจมีการเปลี่ยนแปลงเล็กน้อยและฉันสามารถทำได้;)
Tony O'Hagan

1
คุณไม่ควรทำการเปลี่ยนแปลงตารางโดยใช้ GUI มันจะสร้างตารางขึ้นใหม่อย่างสมบูรณ์แทนที่จะใช้ตาราง Alter และจะทำให้เกิดปัญหาหากคุณไม่เลือกตัวเลือกนี้และตารางมีขนาดใหญ่ นอกจากนี้คุณควรมีการเปลี่ยนแปลงทั้งหมดในตารางในสคริปต์ในการควบคุมแหล่งที่มา
HLGEM

ไม่ว่าในกรณีใด ๆ ไม่มีเหตุผลใดที่จะใช้ GUI เพื่อออกแบบตารางหรือเปลี่ยนแปลงและไม่มีเหตุผลที่ดีที่จะทำ การเปลี่ยนแปลงทั้งหมดจะต้องอยู่ในสคริปต์เพื่อให้สามารถเผยแพร่ไปยังเซิร์ฟเวอร์อื่น ๆ และรับการปฏิบัติเช่นเดียวกับรหัสที่พวกเขาอยู่ในการควบคุมแหล่งที่มา
HLGEM

5

ถ้าคุณใช้ T-SQL (MSSQL); คุณควรลองใช้สคริปต์นี้:

ALTER TABLE [Employee] ALTER COLUMN [Salary] NUMERIC(22,5)

ถ้าคุณใช้ MySQL คุณควรลองใช้สคริปต์นี้:

ALTER TABLE [Employee] MODIFY COLUMN [Salary] NUMERIC(22,5)

ถ้าคุณใช้ Oracle คุณควรลองใช้สคริปต์นี้:

ALTER TABLE [Employee] MODIFY [Salary] NUMERIC(22,5)

3

ไปที่เครื่องมือออกแบบตัวเลือกออกแบบตารางและฐานข้อมูลและยกเลิกการเลือกป้องกันการบันทึกป้อนคำอธิบายรูปภาพที่นี่


1
คุณไม่ควรทำการเปลี่ยนแปลงตารางโดยใช้ GUI มันจะสร้างตารางขึ้นใหม่อย่างสมบูรณ์แทนที่จะใช้ตาราง Alter และจะทำให้เกิดปัญหาหากคุณไม่เลือกตัวเลือกนี้และตารางมีขนาดใหญ่ นอกจากนี้คุณควรมีการเปลี่ยนแปลงทั้งหมดในตารางในสคริปต์ในการควบคุมแหล่งที่มา
HLGEM

2

แก้ไขชนิดข้อมูลคอลัมน์ด้วยประเภทการตรวจสอบของคอลัมน์:

IF EXISTS(
       SELECT 1
       FROM   sys.columns
       WHERE  NAME = 'YourColumnName'
              AND [object_id] = OBJECT_ID('dbo.YourTable')
              AND TYPE_NAME(system_type_id) = 'int'
   )
    ALTER TABLE dbo.YourTable ALTER COLUMN YourColumnName BIT

1

สำหรับฉันใน sql server 2016 ฉันทำแบบนี้

* หากต้องการเปลี่ยนชื่อคอลัมน์ Column1 เป็น column2

EXEC sp_rename 'dbo.T_Table1.Column1', 'Column2', 'COLUMN'

* หากต้องการแก้ไขคอลัมน์ประเภทจากสตริงเป็นint :( โปรดตรวจสอบให้แน่ใจว่าข้อมูลอยู่ในรูปแบบที่ถูกต้อง )

ALTER TABLE dbo.T_Table1 ALTER COLUMN Column2  int; 

0

ในรุ่นกะทัดรัดจะมีขนาดโดยอัตโนมัติสำหรับชนิดข้อมูลวันที่และเวลา (8) ดังนั้นไม่จำเป็นต้องกำหนดขนาดของฟิลด์และสร้างข้อผิดพลาดสำหรับการดำเนินการนี้ ...


-2

ฉันสามารถแก้ไขประเภทข้อมูลของเขตข้อมูลตารางด้วยแบบสอบถามต่อไปนี้: และใน Oracle DB ด้วย

ALTER TABLE table_name
MODIFY column_name datatype;

ไม่ได้อยู่ในเซิร์ฟเวอร์ SQl
HLGEM

-4

แทนที่ประเภทข้อมูลโดยไม่สูญเสียข้อมูล

alter table tablename modify columnn  newdatatype(size);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.