Estou tentando criar um procedimento armazenado para converter todas as ntext
colunas do meu banco de dados em arquivos nvarchar(max)
.
Este é o código
ALTER PROCEDURE [dbo].[usp_SL_ConvertNtextToNvarchar]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @table_name nvarchar(128)
DECLARE @column_name nvarchar(128)
DECLARE @totalCount int
DECLARE @count int
SET @totalCount = 0;
SET @count = 0;
-- Eventlogic
DECLARE tables_cursor CURSOR FOR
SELECT so.name as table_name, sc.name as column_name
FROM sys.objects so
JOIN sys.columns sc ON so.object_id = sc.object_id
JOIN sys.types stp ON sc.user_type_id = stp.user_type_id
AND stp.name = 'ntext'
WHERE so.type = 'U' -- to show only user tables
OPEN tables_cursor
FETCH NEXT FROM tables_cursor INTO @table_name, @column_name
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC ('ALTER TABLE Eventlogic.dbo.' + @table_name + ' ALTER COLUMN ' + @column_name + ' nvarchar(max);')
EXEC ('UPDATE Eventlogic.dbo.' + @table_name + ' SET ' + @column_name + '=' + @column_name + ' ')
SET @count = @count + 1;
IF @count > 0
PRINT ('Eventlogic.dbo.' + @table_name + '.' + @column_name + ' ' + CAST(@count AS nvarchar(10)))
SET @totalCount = @totalCount + @count;
FETCH NEXT FROM tables_cursor INTO @table_name, @column_name
END
CLOSE tables_cursor
DEALLOCATE tables_cursor
PRINT ('Total columns updated: ' + CAST(@totalCount AS nvarchar(10)))
END;
Sempre que tento executá-lo, recebo este erro:
Msg 16924, Nível 16, Estado 1, Procedimento usp_SL_ConvertNtextToNvarchar, Linha 37
Cursorfetch: O número de variáveis declaradas na lista INTO deve corresponder ao das colunas selecionadas.
Temos 338 colunas em tabelas diferentes como ntext
, devido ao legado.
Atualizamos para o SQL Server 2008 R2, portanto, gostaríamos de converter essas colunas em arquivos nvarchar(max)
.
Queremos seguir o conselho aqui ntext vs nvarchar(max) onde Conwell sugere fazer a atualização após a alteração.
O servidor SQL move o texto da estrutura LOB para a tabela (se for menor que 8.000 bytes). Portanto, quando executamos o select novamente com IO STATISTICS, obtemos 0 leituras de LOB.
Qualquer ajuda com esse erro seria ótima.
ATUALIZAR
Código atualizado como Martin mencionou. Na verdade, está alterando apenas o primeiro da lista antes de dar o erro.
2ª ATUALIZAÇÃO
Depois de fazer as alterações no código para corrigir a segunda busca, fechei o SQL Management Studio. Abri o SQL Management Studio novamente e executei e funcionou. Então, obrigado Martin novamente.
Desde já, obrigado.
Federico
Embora se você resolver isso antes de ler minha resposta, tornando improvável que seja útil para o seu caso específico (a menos que você precise fazer isso em vários bancos de dados), prefiro a concatenação de strings em vez de cursores para esse tipo de trabalho. Principalmente porque você pode imprimir a string em vez de executá-la, verificando se pelo menos o primeiro valor de 8K parece adequado e correto.
Quando estiver satisfeito com o
PRINT
resultado, remova o comentárioEXEC
e execute-o novamente.O script de Jon Seigel oferece funcionalidade adicional (lidando com colunas que participam de índices FULLTEXT).
Ok, eu reescrevi seu SP para você com
QUOTENAME
oschema
que @MartinSmith sugeriu. Embora eu não saiba ao certo por que você está usando um SP para isso. Parece que um pedaço de código autônomo sem o wrapper SP faria mais sentido para algo assim.Você usa
QUOTENAME
para lidar com caracteres estranhos no nome. Por exemploTable-Test
, é um nome de tabela válido, mas não funcionará em seu código, a menos que você coloque[]
s em torno dele[Table-Test]
.QUOTENAME
cuida disso para você. Ele também lida se você tiver ']'s em seu nome também. Geralmente é considerada uma prática recomendada quando você está fazendo sql dinâmico para incluirschemas
e usarQUOTENAME
quando necessário.Abaixo está uma variação que irá imprimir os demonstrativos para você analisar e então você poderá executá-los: