我继承了我需要使用的数据库。所有数字字段都设置为bigint(没有理由它们都是5000以下)。
我如何编程将big int的所有列更改为int?这是否可能导致任何现有约束等问题?
我只想更改表格,只在我正在处理的特定数据库中。
我正在使用SQL Server 2008 R2
我需要为数百个字段执行此操作我正在寻找可以运行一次的内容,它将对所有表字段执行所有更新。我想保留任何现有的约束,空状态和默认值。
因此,基本上数据库范围内的bigint更改为int而不更改除字段类型之外的任何内容。
由于
答案 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,右键单击必要的数据库=>任务=>生成脚本。
下一个=>下一步
此时按先进。会有一个弹出窗口。将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)
我会这样做:
我想这会是最快的。如果逐列进行,则需要逐列转换。这涉及很多可能成为问题的IO,具体取决于表的大小。
关心GJ
答案 4 :(得分:0)
id除了答案之外,别忘了检查列上的所有值是否在整数范围内(-2,147,483,648和2,147,483,647之间)。
要自动化@Oleg Dok的答案,您可以在脚本中运行他的解决方案,该脚本循环遍历数据库中的所有表和所有列