MS SQL Server (Ver 2008 or above) - 如何根据我的ID列重新创建自动增量

MS SQL Server (Ver 2008 or above) - How to recreate auto-incremental based in my ID column

我在 csv 文件中有一个 table(ID 为 numeric)。

我手动将文件中的信息上传到 SQL 服务器数据 table(将我的 ID 列创建为 numeric)。

但是,我想将我的 ID 列重新创建为自动数字 ID 列,以继续最新条目的数字。

示例:table 的 ID 为 1、5、10。我想重新创建自动增量 (IDENTITY) ID 列(保留我的旧 ID)并继续使用 ID 11 插入下一行。

我想没有一种方法可以实现这一点。但是我想知道我应该遵循的步骤。

这是一个脚本,可以让您了解一种方法。

IF OBJECT_ID('DELETEME.dbo.Tbl') IS NOT NULL
    BEGIN
        DROP TABLE Tbl
    END

IF OBJECT_ID('DELETEME.dbo.stageTbl') IS NOT NULL
    BEGIN
        DROP TABLE stageTbl
    END

CREATE TABLE Tbl (
    ID INT
    ,A CHAR(1)
)

INSERT INTO Tbl VALUES (1,'A'),(2,'B'),(10,'C')

SELECT *
FROM
    Tbl

EXEC sp_rename 'DELETEME.dbo.Tbl', 'stageTbl', 'OBJECT'
--renames original table

--create script for the new table
CREATE TABLE Tbl (
    ID INT NOT NULL IDENTITY(1,1)
    ,A CHAR(1)
)


--have to set IDENTITY_INSERT on to insert the ID into an IDENTITY column
SET IDENTITY_INSERT Tbl ON

INSERT INTO Tbl (ID, A)
SELECT ID, A
FROM
    stageTbl

SET IDENTITY_INSERT Tbl OFF

DROP TABLE stageTbl
--drops original table

DBCC CHECKIDENT('Tbl', RESEED, 222)
--sets the number you want to with next if you set as 222 the next identity will be 223

INSERT INTO Tbl (A) VALUES ('D')

SELECT *
FROM
    Tbl

基本步骤

  • 重命名原始 Table(如果您希望新的 table 与旧的同名,我喜欢先重命名,因为新的 [= 会自动生成约束名称等36=])
  • 创建新的 table 并将列作为标识列
  • 开启IDENTITY_INSERT
  • Select所有记录从旧的table到新的
  • 关闭IDENTITY_INSERT
  • 你不必这样做,但你可以 RESSED 身份以你想要的任何数字开头,否则 SQL-服务器将根据最大 ID 值自动执行此操作。
  • 删除您重命名的原始 table

感谢马特帮我解决了最初的问题。 我想分享一个我用来自动执行所有必要步骤的 C# 方法:

--免责声明:this的使用是我的class连接MSSQL服务器,用来读SELECT句(而returns 一个 DataTable) 并执行 SQL 查询等。希望有人能找到有用的代码 (AS-IS) --

/// <summary> Recreate an ID with auto-incremental when the table has the ID without this option.
/// <para>Automatically will rename the original table to TABLENAME_TO_DELETE (The process will require copy and recreate the table, then the process will duplicate the information) </para></summary>
/// <param name="strTable">SQL table</param>
/// <param name="strId">ID column</param>
public string recreateIdentityColumn(string strTable, string strId)
{
    string strLog = "Table: {0} - ID: {1}".fwFormat(strTable, strId);

    string strNewTable = strTable + "_" + fw.rnd(1, 1000).ToString() + fw.rnd(5000, 10000);
    DataTable dtTable = this.fillDataTable("SELECT COLUMN_NAME, DATA_TYPE, NUMERIC_PRECISION, NUMERIC_SCALE " +
                                            "FROM Information_SCHEMA.COLUMNS " +
                                            "WHERE TABLE_NAME = '" + strTable + "'");

    if (!dtTable.fwHasData()) throw new Exception("The current table '" + strTable + "' doesn't exists");
    DataRow[] drIdInfo = dtTable.Select("COLUMN_NAME = '" + strId + "'");

    if (!drIdInfo.fwHasData()) throw new Exception("The ID column '" + strId + "' doesn't exists in the table '" + strTable + "'");

    string strIdType = "";
    string strColumns = "";

    strIdType = drIdInfo[0]["DATA_TYPE"].fwEmpty("");

    if (strIdType.fwContains("decimal"))
        strIdType += "({0}, {1})".fwFormat(drIdInfo[0]["NUMERIC_PRECISION"].ToString(), drIdInfo[0]["NUMERIC_SCALE"].ToString());

    strLog += "\r\nID DataType: " + strIdType;

    foreach (DataRow drInfo in dtTable.Rows)
        strColumns += ",[" + drInfo["COLUMN_NAME"].ToString() + "]";

    strId = "[" + strId.TrimStart('[').TrimEnd(']') + "]";
    strColumns = strColumns.TrimStart(',');
    strLog += "\r\nColumns: " + strColumns;

    try
    {
        // Rule 1: Clone the table (Only the structure)
        this.executeQuery("SELECT TOP 0 * INTO " + strNewTable + " FROM " + strTable);

        // Rule 2: Remove the ID from the clone table
        this.executeQuery("ALTER TABLE " + strNewTable + " DROP COLUMN " + strId);

        // Rule 3: Add the ID column with the identity property
        this.executeQuery("ALTER TABLE " + strNewTable + " ADD " + strId + " " + strIdType + " IDENTITY(1,1)");

        // Rule 4: Allow manual insertion of ID in the identity column
        this.executeQuery("SET IDENTITY_INSERT " + strNewTable + " ON");

        // Rule 5: Copy the rows into the table
        int intTotalRows = this.rowCount(strTable);
        int intTotalNewRows = this.executeQuery("INSERT INTO " + strNewTable + "(" + strColumns + ") " +
                            "SELECT " + strColumns + " FROM " + strTable);

        strLog += "\r\nOriginal rows {0} - New rows {1}".fwFormat(intTotalRows.ToString(), intTotalNewRows.ToString());

        // Rule 6: Return the insertion of identity rows to a normal state
        this.executeQuery("SET IDENTITY_INSERT " + strNewTable + " OFF");

        // Rule 7: Rename the table with NO IDENTITY as OLD and rename the table with INDENTITY ID as NEW/ACTUAL
        this.executeQuery("EXEC sp_rename '" + strTable + "', '" + strTable + "_TO_DELETE', 'OBJECT'");
        this.executeQuery("EXEC sp_rename '" + strNewTable + "', '" + strTable + "', 'OBJECT'");
        strLog += "\r\nProcess run without problems";
        return strLog;
    }
    catch (Exception ex)
    {
        strLog += "\r\nException occur";
        throw ex;
    }
}