Solución:
Como no encontré una forma adecuada, escribí un guión para hacerlo y lo comparto aquí para aquellos que lo necesiten. El script se ejecuta a través de todas las tablas de usuario y recopila las columnas. Si el tipo de columna es de cualquier tipo, intenta convertirlo a la colación dada.
Las columnas deben estar libres de índices y restricciones para que esto funcione.
Si alguien todavía tiene una mejor solución para esto, por favor publíquela.
DECLARE @collate nvarchar(100);
DECLARE @table nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @row_id int;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);
SET @collate="Latin1_General_CI_AS";
DECLARE local_table_cursor CURSOR FOR
SELECT [name]
FROM sysobjects
WHERE OBJECTPROPERTY(id, N'IsUserTable') = 1
OPEN local_table_cursor
FETCH NEXT FROM local_table_cursor
INTO @table
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE local_change_cursor CURSOR FOR
SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS row_id
, c.name column_name
, t.Name data_type
, c.max_length
, c.column_id
FROM sys.columns c
JOIN sys.types t ON c.system_type_id = t.system_type_id
LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE c.object_id = OBJECT_ID(@table)
ORDER BY c.column_id
OPEN local_change_cursor
FETCH NEXT FROM local_change_cursor
INTO @row_id, @column_name, @data_type, @max_length, @column_id
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@max_length = -1) OR (@max_length > 4000) SET @max_length = 4000;
IF (@data_type LIKE '%char%')
BEGIN TRY
SET @sql="ALTER TABLE " + @table + ' ALTER COLUMN ' + @column_name + ' ' + @data_type + '(' + CAST(@max_length AS nvarchar(100)) + ') COLLATE ' + @collate
PRINT @sql
EXEC sp_executesql @sql
END TRY
BEGIN CATCH
PRINT 'ERROR: Some index or constraint rely on the column' + @column_name + '. No conversion possible.'
PRINT @sql
END CATCH
FETCH NEXT FROM local_change_cursor
INTO @row_id, @column_name, @data_type, @max_length, @column_id
END
CLOSE local_change_cursor
DEALLOCATE local_change_cursor
FETCH NEXT FROM local_table_cursor
INTO @table
END
CLOSE local_table_cursor
DEALLOCATE local_table_cursor
GO
Así que aquí estoy, una vez más, no satisfecho con la respuesta. Se me asignó la tarea de actualizar JIRA 6.4.xa JIRA Software 7.xy fui a ese problema en particular con la base de datos y la clasificación de columnas.
En SQL Server, si no elimina restricciones como la clave principal o la clave externa o incluso los índices, la secuencia de comandos proporcionada anteriormente como respuesta no funciona en absoluto. Sin embargo, cambiará aquellos que no tengan esas propiedades. Esto es realmente problemático, porque no quiero eliminar manualmente todas las restricciones y volver a crearlas. Esa operación probablemente podría terminar con errores. Por otro lado, crear un script que automatice el cambio podría llevar años.
Entonces encontré una manera de realizar la migración simplemente usando SQL Management Studio. Este es el procedimiento:
- Cambie el nombre de la base de datos por otra cosa. Por ejemplo, el mío era “Jira”, así que lo renombré “JiraTemp”.
- Cree una nueva base de datos llamada “Jira” y asegúrese de establecer la intercalación correcta. Simplemente seleccione la página “Opciones” y cambie la colación.
- Una vez creado, vuelva a “JiraTemp”, haga clic con el botón derecho en “Tareas -> Generar scripts …”.
- Seleccione “Secuencia de comandos de toda la base de datos y todos los objetos de la base de datos”.
- Seleccione “Guardar en una nueva ventana de consulta”, luego seleccione “Avanzado”
- Cambie el valor de “Script para la versión del servidor” por el valor deseado
- Habilite “Permisos de nivel de objeto de secuencia de comandos”, “Propietario de secuencia de comandos” e “Índices de texto completo de secuencia de comandos”
- Deje todo lo demás como está o personalícelo si lo desea.
- Una vez generada, elimine la sección “CREAR BASE DE DATOS”. Reemplaza “JiraTemp” por “Jira”.
- Ejecute el script. Toda la estructura de la base de datos y los permisos de la base de datos ahora se replican en “Jira”.
- Antes de copiar los datos, debemos deshabilitar todas las restricciones. Ejecute el siguiente comando para hacerlo en la base de datos “Jira”:
EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"
- Ahora es necesario transferir los datos. Para hacerlo, simplemente haga clic derecho en “JiraTemp”, luego seleccione “Tareas -> Exportar datos …”
- Seleccione como origen y destino de datos el proveedor OLE DB para SQL Server.
- La base de datos de origen es “JiraTemp”
- La base de datos de destino es “Jira”
- El nombre del servidor es técnicamente el mismo para el origen y el destino (excepto si ha creado la base de datos en otro servidor).
- Seleccione “Copiar datos de una u otra tabla o vista”.
- Seleccione todas las tablas excepto las vistas. Luego, cuando aún esté resaltado, haga clic en “Editar asignaciones”. Marque “Habilitar inserción de identidad”
- Haga clic en Aceptar, Siguiente y luego en Finalizar.
- La transferencia de datos puede tardar un poco. Una vez terminado, ejecute el siguiente comando para volver a habilitar todas las restricciones:
exec sp_msforeachtable @command1="print '?'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"
Una vez completado, reinicié JIRA y la recopilación de mi base de datos estaba en orden. ¡Espero que ayude a mucha gente!
Problema de longitud fija nvarchar y agregado NULL / NOT NULL
DECLARE @collate nvarchar(100);
DECLARE @table nvarchar(255);
DECLARE @column_name nvarchar(255);
DECLARE @column_id int;
DECLARE @data_type nvarchar(255);
DECLARE @max_length int;
DECLARE @row_id int;
DECLARE @sql nvarchar(max);
DECLARE @sql_column nvarchar(max);
DECLARE @is_Nullable bit;
DECLARE @null nvarchar(25);
SET @collate="Latin1_General_CI_AS";
DECLARE local_table_cursor CURSOR FOR
SELECT [name]
FROM sysobjects
WHERE OBJECTPROPERTY(id, N'IsUserTable') = 1
OPEN local_table_cursor
FETCH NEXT FROM local_table_cursor
INTO @table
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE local_change_cursor CURSOR FOR
SELECT ROW_NUMBER() OVER (ORDER BY c.column_id) AS row_id
, c.name column_name
, t.Name data_type
, c.max_length
, c.column_id
, c.is_nullable
FROM sys.columns c
JOIN sys.types t ON c.system_type_id = t.system_type_id
LEFT OUTER JOIN sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE c.object_id = OBJECT_ID(@table)
ORDER BY c.column_id
OPEN local_change_cursor
FETCH NEXT FROM local_change_cursor
INTO @row_id, @column_name, @data_type, @max_length, @column_id, @is_nullable
WHILE @@FETCH_STATUS = 0
BEGIN
IF (@max_length = -1) SET @max_length = 4000;
set @null=" NOT NULL"
if (@is_nullable = 1) Set @null=" NULL"
if (@Data_type="nvarchar") set @max_length=cast(@max_length/2 as bigint)
IF (@data_type LIKE '%char%')
BEGIN TRY
SET @sql="ALTER TABLE " + @table + ' ALTER COLUMN [' + rtrim(@column_name) + '] ' + @data_type + '(' + CAST(@max_length AS nvarchar(100)) + ') COLLATE ' + @collate + @null
PRINT @sql
EXEC sp_executesql @sql
END TRY
BEGIN CATCH
PRINT 'ERROR: Some index or contraint rely on the column ' + @column_name + '. No conversion possible.'
PRINT @sql
END CATCH
FETCH NEXT FROM local_change_cursor
INTO @row_id, @column_name, @data_type, @max_length, @column_id, @is_Nullable
END
CLOSE local_change_cursor
DEALLOCATE local_change_cursor
FETCH NEXT FROM local_table_cursor
INTO @table
END
CLOSE local_table_cursor
DEALLOCATE local_table_cursor
GO