【问题标题】:SQL Server Change Primary Key Data TypeSQL Server 更改主键数据类型
【发布时间】:2017-01-09 13:50:50
【问题描述】:

我正在处理SQL Server 2012:

我有一个主键列为INT 的表。我需要将其更改为 GUID

我是否要更改表格并将 int 列删除为primary key

添加 GUID 列并将其设置为 Primary 并删除旧的 INT 列?

谢谢。

【问题讨论】:

    标签: sql-server-2012 primary-key


    【解决方案1】:

    您不能更改主键列,除非您删除它。任何更改其数据类型的操作都会导致以下错误..

    对象“XXXX”依赖于列“XXXX”。

    唯一的选择是

    1.删除主键
    2.更改数据类型
    3.重新创建主键

    ALTER TABLE t1  
    DROP CONSTRAINT PK__t1__3213E83F88CF144D;   
    GO  
    
    alter table t1 
    alter column id varchar(10) not null
    
    alter table t1 add primary key (id)
    

    从 2012 年开始,有一个名为 (DROP_EXISTING = ON) 的子句使事情变得简单,通过在最后阶段删除聚集索引并保持旧索引可用于所有操作。但在您的情况下,此子句将不起作用。 .

    所以我推荐

    1.使用不同的名称创建具有所需架构和索引的新表
    2.从旧表插入数据到新表
    3.最后在切换的时候,插入积累的数据
    4.将表重命名为旧表名

    这样您可能会减少停机时间

    【讨论】:

      【解决方案2】:

      您可以分三步更改主键的日期类型

      第 1 步:- 删除与主键关联的约束

      ALTER TABLE table_name
       DROP CONSTRAINT constraint_name;
      

      第 2 步:- 将主键列更改为有效的主键数据类型

      ALTER TABLE  table_name
      ALTER COLUMN pk_column_name target_data_type(size) not null;
      

      第 3 步 :- 再次创建更改后的列主键

      ALTER TABLE table_name
      ADD PRIMARY KEY (pk_column_name);
      

      PS :-

      • 当您尝试更改约束时,您可以从错误消息中获取约束名称 pk_column

      • 如果 pk_column 中已有数据,请确保该列的源数据类型和目标数据类型都可用于现有数据。否则需要另外两个步骤将现有数据移动到临时列,然后执行这些步骤并在审查和删除该临时列后恢复该数据。


      【讨论】:

      • 最佳答案
      • 更好的答案,更好的解释和格式:)
      • 我只需要执行第 2 步——它不需要我在更改列类型之前删除主键约束。
      【解决方案3】:

      下面是我编写的一个脚本,用于帮助我们部署对主键列数据类型的更改。

      此脚本假定根据该列不存在任何非主键约束(例如外键)。

      它有一些安全检查,因为它被设计为部署到不同的服务器(dev、uat、live)如果服务器上的表因某种原因不同而不会产生副作用。

      我希望这对某人有所帮助。如果您在投票前发现任何问题,请告诉我。我非常乐意更新脚本。

      IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C WITH (NOLOCK) WHERE C.TABLE_CATALOG = '<<DB>>' AND C.TABLE_SCHEMA = 'dbo' AND C.TABLE_NAME = '<<Table>>' 
      AND C.COLUMN_NAME = '<<COLUMN>>' AND C.DATA_TYPE = 'int') -- <- Additional test to check the current datatype so this won't make unnecessary or wrong updates
      BEGIN
          DECLARE @pkName VARCHAR(200);
          SELECT @pkName = pkRef.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pkRef WITH (NOLOCK)
          WHERE pkRef.TABLE_CATALOG = '<<DB>>' AND pkRef.TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '<<Table>>'
      
          IF(@pkName IS NOT NULL)
          BEGIN
              -- Make sure the primary key name is the one you are going to use in script beyond this point.
              IF(@pkName != '<<PRIMARY KEY NAME>>') 
              BEGIN
                  RAISERROR ('Unexpected primary key name - The primary key found has a different name than expected. Please update the script.', 16, 1);
                  RETURN;
              END
      
              ALTER TABLE dbo.<<Table>>
                    DROP CONSTRAINT <<PRIMARY KEY NAME>>; -- Note: this is not a string or a variable (just type the PK name)
              SELECT 'Dropped existing primary key';
          END
      
          ALTER TABLE dbo.<<Table>> ALTER COLUMN ID BIGINT
          SELECT 'Updated column type to big int';
      
          ALTER TABLE dbo.<<Table>>
                ADD CONSTRAINT <<PRIMARY KEY NAME>> PRIMARY KEY CLUSTERED (<<COLUMN>>);
          SELECT 'Created the primary key';
      END
      ELSE
      BEGIN
          SELECT 'No change required.';
      END
      

      【讨论】:

        【解决方案4】:

        如果其他表使用索引 FK 引用您的 PK,这些是您必须遵循的步骤。

        在本例中,主表名为Main,单引用表Reference。我将数据类型更改为NVARCHAR(7)。要使用它:

        • 用您自己的查找/替换所有这些表名;
        • 修改数据类型;
        • 您可能还需要单独查找/替换 dbo 架构;
        • 我正在使用包含约束名称的语法 - 如果您愿意,也可以将它们更新为您喜欢的命名约定。
        ALTER TABLE dbo.Main ADD IdNew NVARCHAR(7);
        UPDATE dbo.Main SET IdNew = Id;
        
        -- For all tables with FK's to this Main:
        
        ALTER TABLE dbo.Reference ADD MainIdNew NVARCHAR(7);
        UPDATE dbo.Reference SET MainIdNew = MainId;
        
        ALTER TABLE dbo.Reference DROP CONSTRAINT FK_Reference_MainId_Main_Id;
        DROP INDEX IX_Reference_MainId ON dbo.Reference;
        ALTER TABLE dbo.Reference DROP COLUMN MainId;
        
        -- Until here
        
        ALTER TABLE dbo.Main DROP CONSTRAINT PK_Main;
        ALTER TABLE dbo.Main DROP COLUMN Id;
        
        EXEC sp_rename 'dbo.Main.IdNew', 'Id', 'COLUMN';
        ALTER TABLE dbo.Main ALTER COLUMN Id NVARCHAR(7) NOT NULL;
        ALTER TABLE dbo.Main ADD CONSTRAINT PK_Main PRIMARY KEY (Id);
        
        -- Again for all tables with FK's to this Main:
        
        EXEC sp_rename 'dbo.Reference.MainIdNew', 'MainId', 'COLUMN';
        ALTER TABLE dbo.Reference ADD CONSTRAINT FK_Reference_MainId_Main_Id FOREIGN KEY (MainId) REFERENCES dbo.Main(Id);
        CREATE INDEX IX_Reference_MainId ON dbo.Reference(MainId);
        

        【讨论】:

          【解决方案5】:

          在表格右边你要改变PK类型>>修改。进入列,更改类型并保存。如果你想看到这样的改变的代码,在保存之前,你可以右击>>“生成改变脚本..”。

          【讨论】:

          • 那使用?什么工具?他有没有提到他使用的工具是什么?
          【解决方案6】:

          使用Microsoft SQL Server Management Studio 执行以下操作:

          1. 打开表Design
          2. 更改主键列类型或任何其他也可以通过这种方式进行的更改
          3. 在设计区右击选择Generate Change Script
          4. 接受Validation Warning
          5. 预览更改或将其保存在文件中。
          6. 利润:)

          这适用于对表的任何更改,请记住 SSMS 会创建一个临时的第二个表来执行诸如主列类型更改之类的困难更改。

          这适用于我的应用程序版本 18.9。​​

          【讨论】:

            猜你喜欢
            • 2010-09-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-17
            • 2017-04-05
            相关资源
            最近更新 更多