SQL Serverデータベースがあり、大きな数字で始まったため、ID列を変更したい 10010
別のテーブルに関連しているためです。現在200レコードあり、レコードが増える前にこの問題を修正したいと思います。
この列を変更またはリセットする最良の方法は何ですか?
SQL Serverデータベースがあり、大きな数字で始まったため、ID列を変更したい 10010
別のテーブルに関連しているためです。現在200レコードあり、レコードが増える前にこの問題を修正したいと思います。
この列を変更またはリセットする最良の方法は何ですか?
回答:
ID列を更新できません。
SQL Serverでは、更新ステートメントを使用して他の列で実行できることとは異なり、ID列を更新できません。
同様の要件を達成するためのいくつかの代替策がありますが。
テーブルの現在のID値をチェックし、必要に応じてID値を変更するDBCC CHECKIDENT を使用します。
DBCC CHECKIDENT('tableName', RESEED, NEW_RESEED_VALUE)
IDENTITY_INSERT を使用すると、明示的な値をテーブルのID列に挿入できます。
SET IDENTITY_INSERT YourTable {ON|OFF}
例:
-- Set Identity insert on so that value can be inserted into this column
SET IDENTITY_INSERT YourTable ON
GO
-- Insert the record which you want to update with new value in the identity column
INSERT INTO YourTable(IdentityCol, otherCol) VALUES(13,'myValue')
GO
-- Delete the old row of which you have inserted a copy (above) (make sure about FK's)
DELETE FROM YourTable WHERE ID=3
GO
--Now set the idenetity_insert OFF to back to the previous track
SET IDENTITY_INSERT YourTable OFF
UPDATE YourTable SET IdentityCol = 13
。SET IDENTITY_INSERT YourTable ON
INSERTのみを許可し、UPDATEは許可しません。
あなたの質問が正しいなら、あなたは次のようなことをしたいです
update table
set identity_column_name = some value
簡単に言うと、foreign key
関連付けられている可能性があるため、使用することはお勧めできません。
しかし、これはそれを行うための手順ですback-up
、テーブルを取ってください
手順1-テーブルのデザインビューを選択する
手順2-ID列をオフにする
これでupdate
クエリを使用できます。
次にredo
、ステップ1とステップ2とID列をオンにします
:)
--before running this make sure Foreign key constraints have been removed that reference the ID.
--set table to allow identity to be inserted
SET IDENTITY_INSERT yourTable ON;
GO
--insert everything into a temp table
SELECT *
INTO #tmpYourTable
FROM yourTable
--clear your table
DELETE FROM yourTable
--insert back all the values with the updated ID column
INSERT INTO yourTable (IDCol, OtherCols)
SELECT ID+1 as updatedID --put any other update logic to the ID here
, OtherCols FROM #tmpYourTable
--drop the temp table
DROP TABLE #tmpYourTable
--put identity back to normal
SET IDENTITY_INSERT yourTable OFF;
GO
使用してみてくださいDBCC CHECKIDENT
:
DBCC CHECKIDENT ('YourTable', RESEED, 1);
ID列のない新しいテーブルにテーブルをコピーします。
select columns into newtable from yourtable
ID列を新しいシードでnewtableに追加し、それを主キーにします
ALTER TABLE tableName ADD id MEDIUMINT NOT NULL AUTO_INCREMENT KEY
SET IDENTITY_INSERT dbo.TableName ON
INSERT INTO dbo.TableName
(
TableId, ColumnName1, ColumnName2, ColumnName3
)
VALUES
(
TableId_Value, ColumnName1_Value, ColumnName2_Value, ColumnName3_Value
)
SET IDENTITY_INSERT dbo.TableName OFF
Identity_Insertを使用するときは、列名を含めることを忘れないでください。SQLでは、列名を指定しないと挿入できないためです。
あなたも使うことができます SET IDENTITY INSERT
して、ID列に値を挿入できます。
例:
SET IDENTITY_INSERT dbo.Tool ON
GO
そして、必要な値をID列に挿入できます。
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
update tablename set newcolumnname=value where condition
ただし、上記のコードは、主キーと外部キーの関係がない場合にのみ機能します
コマンドビルダーを使用したC#プログラマ向けの完全なソリューション
まず第一に、あなたはこの事実を知る必要があります:
だから、それを知ったら、あなたは何をしなければならないかです。独自のSQL挿入ステートメントをプログラムするか、独自の挿入コマンドビルダーをプログラムします。または、私がプログラムしたこの1つを使用します。DataTableを指定すると、SQL挿入スクリプトを生成します。
public static string BuildInsertSQLText ( DataTable table )
{
StringBuilder sql = new StringBuilder(1000,5000000);
StringBuilder values = new StringBuilder ( "VALUES (" );
bool bFirst = true;
bool bIdentity = false;
string identityType = null;
foreach(DataRow myRow in table.Rows)
{
sql.Append( "\r\nINSERT INTO " + table.TableName + " (" );
foreach ( DataColumn column in table.Columns )
{
if ( column.AutoIncrement )
{
bIdentity = true;
switch ( column.DataType.Name )
{
case "Int16":
identityType = "smallint";
break;
case "SByte":
identityType = "tinyint";
break;
case "Int64":
identityType = "bigint";
break;
case "Decimal":
identityType = "decimal";
break;
default:
identityType = "int";
break;
}
}
else
{
if ( bFirst )
bFirst = false;
else
{
sql.Append ( ", " );
values.Append ( ", " );
}
sql.Append ("[");
sql.Append ( column.ColumnName );
sql.Append ("]");
//values.Append (myRow[column.ColumnName].ToString() );
if (myRow[column.ColumnName].ToString() == "True")
values.Append("1");
else if (myRow[column.ColumnName].ToString() == "False")
values.Append("0");
else if(myRow[column.ColumnName] == System.DBNull.Value)
values.Append ("NULL");
else if(column.DataType.ToString().Equals("System.String"))
{
values.Append("'"+myRow[column.ColumnName].ToString()+"'");
}
else
values.Append (myRow[column.ColumnName].ToString());
//values.Append (column.DataType.ToString() );
}
}
sql.Append ( ") " );
sql.Append ( values.ToString () );
sql.Append ( ")" );
if ( bIdentity )
{
sql.Append ( "; SELECT CAST(scope_identity() AS " );
sql.Append ( identityType );
sql.Append ( ")" );
}
bFirst = true;
sql.Append(";");
values = new StringBuilder ( "VALUES (" );
} //fin foreach
return sql.ToString ();
}
最初にDBCCを使用して、次に挿入を使用してこの問題を解決しました。たとえば、テーブルが
まず、テーブルの新しい現在のID値をNEW_RESEED_VALUEとして設定します
MyTable {IDCol、colA、colB}
DBCC CHECKIDENT('MyTable', RESEED, NEW_RESEED_VALUE)
その後、あなたは使うことができます
insert into MyTable (colA, ColB) select colA, colB from MyTable
これはすべてのレコードを複製しますが、NEW_RESEED_VALUEで始まる新しいIDCol値を使用します。外部キー参照がある場合、それらを削除または移動すると、より高いID値の重複行を削除できます。
次のコードを使用して新しいテーブルを作成できます。
SELECT IDENTITY (int, 1, 1) AS id, column1, column2
INTO dbo.NewTable
FROM dbo.OldTable
次に、古いデータベースを削除し、新しいデータベースの名前を古いデータベースの名前に変更します。注:column1とcolumn2は、新しいテーブルに保持したい古いテーブルのすべての列を表します。
主キーの値を別の数値に変更する必要がある場合(例:123-> 1123)。identityプロパティは、PK値の変更をブロックします。Set Identity_insertは機能しません。カスケード削除を行っている場合(参照整合性チェックをオフにしない限り)、挿入/削除を行うことはお勧めできません。
このスクリプトは、PKのIDをオフにします。
***********************
sp_configure 'allow update', 1
go
reconfigure with override
go
update syscolumns set colstat = 0 --turn off bit 1 which indicates identity column
where id = object_id('table_name') and name = 'column_name'
go
exec sp_configure 'allow update', 0
go
reconfigure with override
go
***********************
次に、外部キー参照を更新するように関係を設定できます。または、関係の強制をオフにする必要があります。このSOリンクは、T-SQLを使用して外部キー制約を一時的に無効にする方法を示してい ます。
これで、更新を行うことができます。同じ列名に基づいてすべての更新SQLを書き込む短いスクリプトを作成しました(私の場合、CaseIDを1,000,000増やす必要がありました:
select
'update ['+c.table_name+'] SET ['+Column_Name+']=['+Column_Name+']+1000000'
from Information_Schema.Columns as c
JOIN Information_Schema.Tables as t ON t.table_Name=c.table_name and t.Table_Schema=c.table_schema and t.table_type='BASE TABLE'
where Column_Name like 'CaseID' order by Ordinal_position
最後に、参照整合性を再度有効にしてから、主キーのIdentity列を再度有効にします。
注:私はこれらの質問について何人かの人々がなぜ尋ねるのを見ます。私の場合、2番目のインスタンスをシャットダウンできるように、2番目の本番インスタンスのデータをマスターDBにマージする必要があります。操作データのすべてのPK / FKが衝突しないようにする必要があります。メタデータFKは同じです。