テーブル内のいくつかの列のデータ型をALTER
する必要があります。
単一の列の場合、以下が正常に機能します。
ALTER TABLE tblcommodityOHLC
ALTER COLUMN
CC_CommodityContractID NUMERIC(18,0)
しかし、1つのステートメントで複数の列を変更するにはどうすればよいですか?以下は機能しません。
ALTER TABLE tblcommodityOHLC
ALTER COLUMN
CC_CommodityContractID NUMERIC(18,0),
CM_CommodityID NUMERIC(18,0)
これは不可能です。これを1つずつ行う必要があります。
変更した列を含む一時テーブルを作成し、データをコピーし、元のテーブルを削除して、一時テーブルの名前を元の名前に変更できます。
単一のALTER TABLEステートメント内で複数のALTER COLUMNアクションを実行することはできません。
ここでALTER TABLE構文を参照してください。
http://msdn.Microsoft.com/en-US/library/ms190273.aspx
複数のADDまたは複数のDROP COLUMNを実行できますが、ALTER COLUMNは1つだけです。
次のソリューションは、複数の列を変更するための単一のステートメントではありませんが、はい、それは人生を簡単にします:
テーブルのCREATE
スクリプトを生成します。
最初の行のCREATE TABLE
をALTER TABLE [TableName] ALTER COLUMN
に置き換えます
リストから不要な列を削除します。
必要に応じて列のデータ型を変更します。
次のように検索と置換…を実行します。
NULL
、NULL; ALTER TABLE [TableName] ALTER COLUMN
スクリプトを実行します。
それが多くの時間を節約することを願っています:))
他の人が答えたように、複数のALTER TABLEステートメントが必要です。試してください:
ALTER TABLE tblcommodityOHLC alter column CC_CommodityContractID NUMERIC(18,0);
ALTER TABLE tblcommodityOHLC alter column CM_CommodityID NUMERIC(18,0);
等.
他の多くの人が言っているように、変更する列ごとに1つずつ、複数のALTER COLUMN
ステートメントを使用する必要があります。
テーブル内のすべてまたはいくつかの列を同じデータ型に変更する場合(VARCHARフィールドを50文字から100文字に拡張するなど)、以下のクエリを使用してすべてのステートメントを自動的に生成できます。この手法は、複数のフィールドで同じ文字を置換する場合にも役立ちます(すべての列から\ tを削除するなど)。
SELECT
TABLE_CATALOG
,TABLE_SCHEMA
,TABLE_NAME
,COLUMN_NAME
,'ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ALTER COLUMN ['+COLUMN_NAME+'] VARCHAR(300)' as 'code'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'your_table' AND TABLE_SCHEMA = 'your_schema'
これにより、列ごとにALTER TABLE
ステートメントが生成されます。
Management Studioで変更を行い、スクリプトを生成すると、新しいテーブルが作成され、データタイプが変更されたテーブルに古いデータが挿入されます。 2つの列のデータ型を変更する小さな例を次に示します
/*
12 August 201008:30:39
User:
Server: CLPPRGRTEL01\TELSQLEXPRESS
Database: Tracker_3
Application:
*/
/* 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
ALTER TABLE dbo.tblDiary
DROP CONSTRAINT FK_tblDiary_tblDiary_events
GO
ALTER TABLE dbo.tblDiary_events SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_tblDiary
(
Diary_ID int NOT NULL IDENTITY (1, 1),
Date date NOT NULL,
Diary_event_type_ID int NOT NULL,
Notes varchar(MAX) NULL,
Expected_call_volumes real NULL,
Expected_duration real NULL,
Skill_affected smallint NULL
) ON T3_Data_2
TEXTIMAGE_ON T3_Data_2
GO
ALTER TABLE dbo.Tmp_tblDiary SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_tblDiary ON
GO
IF EXISTS(SELECT * FROM dbo.tblDiary)
EXEC('INSERT INTO dbo.Tmp_tblDiary (Diary_ID, Date, Diary_event_type_ID, Notes, Expected_call_volumes, Expected_duration, Skill_affected)
SELECT Diary_ID, Date, Diary_event_type_ID, CONVERT(varchar(MAX), Notes), Expected_call_volumes, Expected_duration, CONVERT(smallint, Skill_affected) FROM dbo.tblDiary WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_tblDiary OFF
GO
DROP TABLE dbo.tblDiary
GO
EXECUTE sp_rename N'dbo.Tmp_tblDiary', N'tblDiary', 'OBJECT'
GO
ALTER TABLE dbo.tblDiary ADD CONSTRAINT
PK_tblDiary PRIMARY KEY NONCLUSTERED
(
Diary_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2
GO
CREATE UNIQUE CLUSTERED INDEX tblDiary_ID ON dbo.tblDiary
(
Diary_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2
GO
CREATE NONCLUSTERED INDEX tblDiary_date ON dbo.tblDiary
(
Date
) WITH( PAD_INDEX = OFF, FILLFACTOR = 86, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON T3_Data_2
GO
ALTER TABLE dbo.tblDiary WITH NOCHECK ADD CONSTRAINT
FK_tblDiary_tblDiary_events FOREIGN KEY
(
Diary_event_type_ID
) REFERENCES dbo.tblDiary_events
(
Diary_event_ID
) ON UPDATE CASCADE
ON DELETE CASCADE
GO
COMMIT
Evanのコードサンプルのおかげで、より多くの変更を加えて、特定の列名で始まり、制約の詳細も処理するテーブルに特定することができました。そのコードを実行し、[CODE]列をコピーして問題なく実行しました。
USE [Table_Name]
GO
SELECT
TABLE_CATALOG
,TABLE_SCHEMA
,TABLE_NAME
,COLUMN_NAME
,DATA_TYPE
,'ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] DROP CONSTRAINT [DEFAULT_'+TABLE_NAME+'_'+COLUMN_NAME+'];
ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ALTER COLUMN ['+COLUMN_NAME+'] datetime2 (7) NOT NULL
ALTER TABLE ['+TABLE_SCHEMA+'].['+TABLE_NAME+'] ADD CONSTRAINT [DEFAULT_'+TABLE_NAME+'_'+COLUMN_NAME+'] DEFAULT (''3/6/2018 6:47:23 PM'') FOR ['+COLUMN_NAME+'];
GO' AS '[CODE]'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'form_%' AND TABLE_SCHEMA = 'dbo'
AND (COLUMN_NAME = 'FormInserted' OR COLUMN_NAME = 'FormUpdated')
AND DATA_TYPE = 'datetime'
select 'ALTER TABLE ' + OBJECT_NAME(o.object_id) +
' ALTER COLUMN ' + c.name + ' DATETIME2 ' +
CASE WHEN c.is_nullable = 0 THEN 'NOT NULL' ELSE 'NULL' END
from sys.objects o
inner join sys.columns c on o.object_id = c.object_id
inner join sys.types t on c.system_type_id = t.system_type_id
where o.type='U'
and c.name = 'Timestamp'
and t.name = 'datetime'
order by OBJECT_NAME(o.object_id)
devio の厚意による
すべてを自分で書いて、すべての列を同じデータ型に変更したくない場合、これにより簡単になります。
select 'alter table tblcommodityOHLC alter column '+name+ 'NUMERIC(18,0);'
from syscolumns where id = object_id('tblcommodityOHLC ')
クエリとして出力をコピーして貼り付けることができます