2012-02-02 281 views
2

我已经继承了我需要使用的数据库。所有的数字字段都被设置为bigint(没有理由,它们全部是5000)。将所有SQL Server列从BigInt更改为Int

我该如何编程mtical将大整数的所有列更改为int?这有可能会导致任何现有的限制等问题?

我只想改变表格,只在特定的数据库中工作。

我使用SQL Server 2008 R2的

我需要为数百场的我期待的东西,我可以运行一次做到这一点,它会做所有的表字段全部更新。我想保留任何现有的约束,空状态和默认值。

所以基本上是一个数据库的bigint更改为int而不改变任何东西,除了字段类型。

感谢

+0

如果他们都是5k以下,那么为什么不使用'smallint'?它只有2个字节,而bigint则只有8个字节,并且值可以高达32k以上。 – JNK 2012-02-02 14:00:03

+0

系统正在扩展,所以它可能会增长到这个尺寸。 – GraemeMiller 2012-02-02 14:02:33

+1

如果您想为每个表自动执行此操作,则可能还需要查看未记录的SP sp_foreachtable。 – gjvdkamp 2012-02-02 14:14:47

回答

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行。所以不需要修改插入语句。

准备就绪需要很长时间。 希望这是有用的。

编辑

这会为你生成一个新的数据库,所以准备好重命名你的原件或新创建的数据库。

+0

.Net似乎并不以像不同的可空int类型之间的转换。它使代码更容易,如果我可以在系统中只有int而不是int和big int的混合 – GraemeMiller 2012-02-02 14:15:34

0

关于马丁·史密斯 - 其备受simplier,比我想象:

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' 

或其中大部分是相同,轻松的空列 - 在执行更新

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' 
+0

添加新栏目有什么意义? 'ALTER TABLE ... ALTER COLUMN'会正常工作,虽然两者都会浪费空间直到重建。 – 2012-02-02 14:02:54

+0

我期待着在很多领域和表格上做到这一点。它可能超过200个领域。任何更自动的? – GraemeMiller 2012-02-02 14:03:48

+0

@MartinSmith没有声明该列可能不可为空 – 2012-02-02 14:06:24

0

我会做这样的:

  1. 重命名YourTable到YourTable_OLD
  2. 右键表 - >脚本表作为创建 - >新的查询窗口
  3. 调整脚本使用int和重命名表到原
  4. 创建新表并将其命名为YourTable,以取代旧
  5. 插入YourTable SELECT * FROM YourTable_OLD
  6. Drop YourTable_OLD(当你确定一切正常时)

我想这会是最快的。如果你一栏一列,它需要逐列转换。这涉及很多可能成为问题的IO,具体取决于您的表的大小。

问候GJ

0

ID除了答案,不要忘记检查一下所有的值的列都在整数范围(-2,147,483,648和2,147,483,647之间)。

要自动@Oleg多克的答案,你可以运行自己的,通过你的DB

2

所有表和所有列循环的脚本里面的解决方案,我认为@Oybek说,这在他的增编一个,我给他+1,但只是为了确定我会概述我该怎么做。 (这里假设你有很多在许多不同的BIGINT表的约束;如果没有,做他们一个接一个可能比较简单。)

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

  • 搜索并用整数替换所有的bigint (慢慢做,确保你只改变需要改变的东西。)

  • 修改脚本来创建一个新的数据库(不同的名字,不同的文件)

  • 运行和创建数据库。

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

如果您像所说的那样,所有的bigint都适合ints,那么您应该没有任何问题;困难的部分是搞清楚如何实际做到这一切。通过SSMS导入或导出向导必须有一些方法来实现,但我并不是那些熟悉这些工具的人。除此之外,根据需要创建一系列INSERT ... SELECT ...语句,按照父节点顺序通过子表执行,并根据需要使用SET IDENTITY INSERTs执行操作。

+0

在生成脚本窗口中,将选项“脚本数据类型”设置为“模式和数据”将创建所有插入具有各种“身份插入”选项的语句。你的回答很简短,简短))) – Oybek 2012-02-02 15:03:59

相关问题