Изменить все столбцы SQL Server с BigInt на Int - PullRequest
2 голосов
/ 02 февраля 2012

Я унаследовал базу данных, с которой мне нужно работать. Все числовые поля были установлены в bigint (без причины они все под 5000).

Как я могу программно изменить все столбцы большого int на int? Это возможно, это вызовет проблему с любыми существующими ограничениями и т. Д.

Я хочу изменять только таблицы и только в конкретной базе данных, над которой я работаю.

Я использую SQL Server 2008 R2

Мне нужно сделать это для сотен полей. Я ищу что-то, что я могу запустить один раз, и все обновления для всех полей таблицы будут выполнены. Я хочу сохранить любые существующие ограничения, нулевой статус и значения по умолчанию.

Таким образом, в общем случае изменение bigint в int в базе данных без каких-либо изменений, кроме типа поля.

Спасибо

Ответы [ 5 ]

7 голосов
/ 02 февраля 2012

Ну, я столкнулся с такой проблемой.Я должен был изменить 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)

РЕДАКТИРОВАТЬ

Если у вас много ограничений, то изменение - это настоящая боль в заднице.Если есть много таблиц с ограничениями и нет особых побуждений к изменению, не делайте этого.

РЕДАКТИРОВАТЬ

Тогда вы можете сделать следующее.Подключитесь к Sql Server через Management Studio, щелкните правой кнопкой мыши необходимую базу данных => Задачи => Сгенерируйте сценарии.

Далее => Далее

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 строк.Таким образом, нет необходимости изменять операторы вставки.

Будьте готовы, это займет много времени.Надеюсь, что это было полезно.

РЕДАКТИРОВАТЬ

Это создаст новую базу данных, поэтому будьте готовы переименовать вашу оригинальную или вновь созданную базу данных.

2 голосов
/ 02 февраля 2012

Я думаю, что @ Ойбек говорит это в одном из своих приложений, я даю ему +1, но просто чтобы быть уверенным, я обрисую, как я это сделаю. (Это предполагает, что у вас есть множество ограничений на множество таблиц bigint; в противном случае выполнение их по одному может быть проще.)

  • Используйте SSMS для сценария всей базы данных. (Это щелкните правой кнопкой мыши базу данных на панели обозревателя объектов, «Сценарий базы данных как», «CREATE TO», и я перейду к ней в новом окне запроса и сохраню ее в виде файла.

  • Поиск и замена всех bigints на целые. (Делайте это медленно, убедитесь, что вы меняете только то, что нужно изменить.)

  • Изменить скрипт для создания новой базы данных (другое имя, разные файлы)

  • Запустите и создайте базу данных.

  • Сложная часть: скопировать данные из таблиц старой базы данных в новую базу данных.

Если, как вы говорите, все значимые вписываются в целые числа, у вас не должно быть никаких проблем; сложная часть - выяснить, как на самом деле все это сделать. Должен быть какой-то способ сделать это с помощью мастера импорта или экспорта SSMS, но я не очень знаком с этими инструментами. За исключением этого, создание последовательности операторов INSERT… SELECT…, выполняемых в порядке родителя через дочерние таблицы, с необходимыми SET IDENTITY INSERT, должно сработать.

0 голосов
/ 02 февраля 2012

В дополнение к ответам, не забудьте проверить, что все значения в столбцах находятся в целочисленном диапазоне (от -2 147 483 648 до 2 147 483 647).

Для автоматизации ответа @Oleg Dok вы можете запустить его решениевнутри скрипта, который перебирает все таблицы и все столбцы в вашей БД

0 голосов
/ 02 февраля 2012

Я бы сделал это так:

  1. Переименуйте YourTable в YourTable_OLD
  2. Таблица правой кнопкой мыши -> Таблица сценариев как Создать -> в новое окно запроса
  3. настроить скрипт для использования int и переименовать таблицу в исходную
  4. Создайте новую таблицу и назовите ее YourTable, чтобы заменить старую
  5. вставить YourTable select * из YourTable_OLD
  6. Drop YourTable_OLD (когда вы уверены, что все прошло нормально)

Полагаю, это будет быстрее. Если вы делаете это столбец за столбцом, он должен преобразовать его столбец за столбцом. Это связано с большим количеством операций ввода-вывода, которые могут стать проблемой, в зависимости от размера вашей таблицы.

С уважением GJ

0 голосов
/ 02 февраля 2012

Что касается Мартина Смита - это намного проще, чем я думал:

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'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...