SQL Server: как изменить столбец INT на BIGINT? [Дубликат]

Ссылка NullReferenceException или Object, не установленная на экземпляр объекта, возникает, когда объект класса, который вы пытаетесь использовать, не создается. Например:

Предположим, что у вас есть класс с именем Student.

public class Student
{
    private string FirstName;
    private string LastName;
    public string GetFullName()
    {
        return FirstName + LastName;
    }
}

Теперь рассмотрим другой класс, в котором вы пытаетесь получить полное имя учащегося.

public class StudentInfo
{      
    public string GetStudentName()
    {
        Student s;
        string fullname = s.GetFullName();
        return fullname;
    }        
}

Как видно из вышеприведенного кода, оператор Student s - объявляет только переменную типа Student, обратите внимание, что класс Student не создается в этой точке. Следовательно, когда выполняется выполнение инструкции s.GetFullName (), она выкинет исключение NullReferenceException.

5
задан Jon Seigel 1 December 2010 в 00:35
поделиться

4 ответа

Кстати, мне пришлось сделать что-то очень похожее около 3 часов назад. Таблица была 35 м строк, она довольно широкая, и на это всегда приходилось делать это:

alter table myTable add myNewColumn int not null default 0;

Вот что я в итоге перешел с:

alter table myTable add myNewColumn int null;

while 1=1
begin
    update top (100000) myTable
    set
        myNewColumn = 0
    where
        myNewColumn is null;

    if @@ROWCOUNT = 0 break;
end

alter table myTable alter column myNewColumn int not null;
alter table myTable add constraint tw_def_myNewColumn default (0) for myNewColumn;

На этот раз операторы alter table были почти мгновенными. Для выполнения пакетов обновления потребовалось около 7-8 минут (на медленном сервере). Я предполагаю, что SQL Server генерирует отмену в моем исходном запросе для восстановления значений, но я не ожидал, что это начнется.

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

8
ответ дан Matt 28 August 2018 в 05:35
поделиться

Я просто столкнулся с этим несколько недель назад со столом с 639-метровыми рядами. Я закончил создание новой таблицы и копирование данных в «партиях». Это заняло около 2 дней на главном сервере, и репликация заняла 3 дня, чтобы воспроизвести все. Затем я изменил все виды и procs, которые использовались для старой таблицы. Это позволило мне убрать несколько проблем, например, избавиться от столбца, который мне не нужен, и выбора (в некоторых случаях) лучших индексов. После того, как все данные были перемещены, sql изменился, я затем уронил старую таблицу.

Беспорядок, но теперь я мудрее. Используйте большие ints для ваших первичных ключей идентификации, если система будет долгоживущей, и есть вероятность нескольких миллионов строк.

0
ответ дан automatic 28 August 2018 в 05:35
поделиться

Я просто столкнулся с этой проблемой ... Таблица с 447 732 310 записями в ней. Если бы коллега придумал удивительное решение, потребовалось бы около 24 минут для копирования данных в новую таблицу, около 40 минут для создания индексов.

Вот что мы сделали:

--Get ntiles of idOrders, split up into 100 groups - 1:20 minutes
IF(OBJECT_ID('TEMPDB..#x')) IS NOT NULL
    DROP TABLE #x

SELECT nt, MIN(idOrder) idOrderMin, MAX(idOrder) idOrderMax
INTO #X
FROM (
       SELECT idOrder, NTILE(100) OVER(ORDER BY idOrder) nt
       FROM (
              SELECT DISTINCT idOrder FROM order_raw_fields
       ) X
) Y
GROUP BY nt

-- view results
--SELECT * FROM #x ORDER BY idOrderMin

-- create new table
SELECT TOP 0 * 
INTO ORDER_RAW_FIELDS_Intl 
FROM ORDER_RAW_FIELDS

ALTER TABLE dbo.ORDER_RAW_FIELDS_Intl
    ALTER COLUMN value nvarchar(500)

--Build queries
SELECT 'insert into ORDER_RAW_FIELDS_Intl select * from order_raw_fields  
where idOrder >= ' + CAST(idOrderMIn AS VARCHAR(100)) + ' and idOrder <= ' + CAST(idOrderMax AS varchar) InsertStmt
    INTO #inserts
FROM #X 
ORDER BY idOrderMin

DECLARE insertCursor CURSOR LOCAL FAST_FORWARD FOR
    SELECT InsertStmt
    FROM #inserts

OPEN insertCursor

-- 24:04 minute execution time to match
DECLARE @insertStmt NVARCHAR(125)
FETCH NEXT FROM insertCursor INTO @insertStmt
WHILE @@FETCH_STATUS = 0
BEGIN
    --EXECUTE @insertStmt
    EXECUTE sp_executesql @statement=@insertStmt

    PRINT 'Execution Complete:  ' + @insertStmt

    FETCH NEXT FROM insertCursor INTO @insertStmt   
END

CLOSE insertCursor
DEALLOCATE insertCursor

-- Add indexes
-- 21:37 minutes completion time
ALTER TABLE [dbo].[ORDER_RAW_FIELDS_Intl] ADD  CONSTRAINT [PK_ORDER_RAW_FIELDS_Intl] PRIMARY KEY CLUSTERED 
(
    [idRow] ASC,
    [idOrder] ASC,
    [remoteFieldName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 92) ON [PRIMARY]
GO

-- 13:45 minutes completion time
CREATE NONCLUSTERED INDEX [IX_idOrder_remoteFieldName2] ON [dbo].[ORDER_RAW_FIELDS_Intl]
(
    [idOrder] ASC,
    [remoteFieldName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 94) ON [PRIMARY]
GO

-- drop table 
TRUNCATE TABLE [dbo].[ORDER_RAW_FIELDS]
DROP TABLE [dbo].[ORDER_RAW_FIELDS]

-- renamed new table to old tables's name
EXEC sp_rename 'ORDER_RAW_FIELDS_Intl', 'ORDER_RAW_FIELDS';
1
ответ дан Gary 28 August 2018 в 05:35
поделиться

создайте новую таблицу, которую вы хотите, с правильными типами столбцов и индексами. (скрипт из старой таблицы и изменение имени.)

вставить в новую таблицу (список столбцов) выберите * из old_table;

переименуйте old_table old_table_back, переименуйте new_table old_table.

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

2
ответ дан tpdi 28 August 2018 в 05:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: