将所有SQL Server列从BigInt更改为Int

时间:2012-02-02 13:57:42

标签: sql-server sql-server-2008-r2

我继承了我需要使用的数据库。所有数字字段都设置为bigint(没有理由它们都是5000以下)。

我如何编程将big int的所有列更改为int?这是否可能导致任何现有约束等问题?

我只想更改表格,只在我正在处理的特定数据库中。

我正在使用SQL Server 2008 R2

我需要为数百个字段执行此操作我正在寻找可以运行一次的内容,它将对所有表字段执行所有更新。我想保留任何现有的约束,空状态和默认值。

因此,基本上数据库范围内的bigint更改为int而不更改除字段类型之外的任何内容。

由于

5 个答案:

答案 0 :(得分:7)

好吧,我遇到过这种问题。我必须将int更改为bigint。这更难,但可能。使用以下语句更改数据类型非常容易:

Alter table myTable alter column targetcolumn int not null

但是,如果您的列涉及约束关系,那么您必须删除约束然后更改然后重新创建约束。

Alter table myTable drop constraint [fkconstraintname]
Alter table myTable alter column targetcolumn int not null
Alter table othertable alter column targetcolumn int not null
Alter table myTable add constraint [fkconstraintname] foreign key (targetcolumn) references othertable(targetcolumn)

修改

如果你有很多限制因素,那么改变它就是一个真正的痛苦。如果有很多有限制的表格,并且没有极端的改变,请不要这样做。

修改

然后你可以做以下事情。通过Management Studio连接到Sql Server,右键单击必要的数据库=>任务=>生成脚本。

下一个=>下一步

Necessary window

此时按先进。会有一个弹出窗口。将Type of data to script设置为架构和数据。选择适合您的输出(文件,查询窗口)?按确定继续。它将为您生成一个完整的DDL和DML,如下所示:

USE [master]
GO
/****** Object:  Database [Zafarga]    Script Date: 02/02/2012 19:31:55 ******/
CREATE DATABASE [Zafarga] ON  PRIMARY 

GO
ALTER DATABASE [Zafarga] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [Zafarga].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [Zafarga] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_NULLS OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_PADDING OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [Zafarga] SET ARITHABORT OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [Zafarga] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [Zafarga] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [Zafarga] SET CURSOR_DEFAULT  GLOBAL
GO
ALTER DATABASE [Zafarga] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [Zafarga] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [Zafarga] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [Zafarga] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [Zafarga] SET  ENABLE_BROKER
GO
ALTER DATABASE [Zafarga] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [Zafarga] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [Zafarga] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [Zafarga] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [Zafarga] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [Zafarga] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [Zafarga] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [Zafarga] SET  READ_WRITE
GO
ALTER DATABASE [Zafarga] SET RECOVERY FULL
GO
ALTER DATABASE [Zafarga] SET  MULTI_USER
GO
ALTER DATABASE [Zafarga] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [Zafarga] SET DB_CHAINING OFF
GO
EXEC sys.sp_db_vardecimal_storage_format N'Zafarga', N'ON'
GO
USE [Zafarga]
GO
/****** Object:  Table [dbo].[Category]    Script Date: 02/02/2012 19:31:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Category](
    [CategoryId] [bigint] IDENTITY(1,1) NOT NULL,
    [CategoryName] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED 
(
    [CategoryId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Product]    Script Date: 02/02/2012 19:31:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Product](
    [ProductId] [bigint] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [Price] [decimal](18, 2) NOT NULL,
    [CategoryId] [bigint] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [ProductId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [Category_Products]    Script Date: 02/02/2012 19:31:56 ******/
ALTER TABLE [dbo].[Product]  WITH CHECK ADD  CONSTRAINT [Category_Products] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[Category] ([CategoryId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [Category_Products]
GO

适当更改所有数据类型,然后运行。

正如您所说,您的所有数据都低于5000行。因此无需修改insert语句。

准备好了需要很长时间。 希望这很有用。

修改

这将为您生成一个新数据库,因此请准备好重命名原始数据库或新创建的数据库。

答案 1 :(得分:2)

我认为@Oybek在他的一个附录中说过,我给他+1,但只是为了确定我会概述我是怎么做的。 (这假设您在许多bigint表中有很多约束;如果没有,逐个执行它们可能会更简单。)

  • 使用SSMS编写整个数据库的脚本。 (这是在对象资源管理器窗格中右键单击数据库,脚本数据库为,创建到,我将它转到新的查询窗口并将其另存为文件。

  • 使用整数搜索并替换所有bigints。 (慢慢来,确保只更改需要更改的内容。)

  • 修改脚本以创建新数据库(不同名称,不同文件)

  • 运行并创建数据库。

  • 困难的部分:将数据从旧数据库的表复制到新数据库。

如果正如你所说的那样,所有重要因素都适用于整体,你应该没有任何问题;困难的部分是弄清楚如何真正做到这一切。必须通过SSMS导入或导出向导来实现这一点,但我并不熟悉这些工具。除此之外,创建一系列INSERT ... SELECT ...语句按父项通过子表的顺序执行,必要时使用SET IDENTITY INSERT,这应该可以解决问题。

答案 2 :(得分:0)

关于马丁史密斯 - 它比我想象的要简单得多:

ALTER TABLE YourTable MODIFY COLUMN OldColumn INT [NOT] NULL

那就是

旧版的答案:

如果新列不可为空:

ALTER TABLE YourTable ADD NewFIeld INT NOT NULL DEFAULT (CAST(OldField AS INT))
GO
ALTER TABLE YourTable DROP COLUMN OldField
GO
exec sp_rename 'YourTable.NewField', 'OldField', 'COLUMN'

对于可为空的列放宽的OR大部分相同 - 在执行更新时不保留系统表上的锁

ALTER TABLE YourTable ADD NewFIeld INT NULL
GO
UPDATE YourTable SET NewField=OldField
GO
ALTER TABLE YourTable DROP COLUMN OldField
GO
exec sp_rename 'YourTable.NewField', 'OldField', 'COLUMN'

答案 3 :(得分:0)

我会这样做:

  1. 将YourTable重命名为YourTable_OLD
  2. 右键单击表格 - >脚本表为Create - >到新的查询窗口
  3. 调整脚本以使用int并将表重命名为原始
  4. 创建新表并将其命名为YourTable以替换旧的
  5. 从YourTable_OLD
  6. 插入YourTable select *
  7. Drop YourTable_OLD(当你确定一切正常时)
  8. 我想这会是最快的。如果逐列进行,则需要逐列转换。这涉及很多可能成为问题的IO,具体取决于表的大小。

    关心GJ

答案 4 :(得分:0)

id除了答案之外,别忘了检查列上的所有值是否在整数范围内(-2,147,483,648和2,147,483,647之间)。

要自动化@Oleg Dok的答案,您可以在脚本中运行他的解决方案,该脚本循环遍历数据库中的所有表和所有列