Ich bin in einer Situation, in der ich eine vorhandene Datenbankstruktur von varchar zu nvarchar mit Hilfe eines Skripts aktualisieren muss. Da dieses Skript jedes Mal ausgeführt wird, wenn eine Konfigurationsanwendung ausgeführt wird, würde ich lieber feststellen, ob eine Spalte bereits in nvarchar geändert wurde und keine Änderung an der Tabelle durchführt. Die Datenbanken, die ich unterstützen müssen, sind SQL Server 2000, 2005 und 2008SQL Server - Skript um Datenbankspalten von varchar auf nvarchar zu aktualisieren, wenn nicht schon nvarchar
9
A
Antwort
2
Die folgende Abfrage sollten Sie bekommen, was Sie brauchen:
IF EXISTS
(SELECT *
FROM sysobjects syo
JOIN syscolumns syc ON
syc.id = syo.id
JOIN systypes syt ON
syt.xtype = syc.xtype
WHERE
syt.name = 'nvarchar' AND
syo.name = 'MY TABLE NAME' AND
syc.name = 'MY COLUMN NAME')
BEGIN
ALTER ...
END
26
Sie können das folgende Skript ausführen, die Ihnen eine Reihe von ALTER geben Befehle:
SELECT 'ALTER TABLE ' + isnull(schema_name(syo.id), 'dbo') + '.' + syo.name
+ ' ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.length when -1 then 'MAX'
ELSE convert(nvarchar(10),syc.length) end + ');'
FROM sysobjects syo
JOIN syscolumns syc ON
syc.id = syo.id
JOIN systypes syt ON
syt.xtype = syc.xtype
WHERE
syt.name = 'varchar'
and syo.xtype='U'
Es gibt jedoch ein paar schnelle für Sie Einsprüche.
- Dies wird nur Tabellen tun. Sie sollten alle Ihre Sprocs und Funktionen überprüfen, um sicherzustellen, dass sie auch in
NVARCHAR
geändert werden. - Wenn Sie eine
VARCHAR
> 4000 haben Sie benötigen, um esNVARCHAR(MAX)
zu modifizieren, aber diese sollten mit dieser Vorlage leicht machbar.
Wenn dies automatisch ausgeführt werden soll, können Sie es in einer WHILE
-Klausel festlegen.
2
das Problem Raum Feste und hinzugefügt Schema
SELECT 'ALTER TABLE [' + isnull(schema_name(syo.object_id), sysc.name) + '].[' + syo.name
+ '] ALTER COLUMN ' + syc.name + ' NVARCHAR(' + case syc.max_length when -1 then 'MAX'
ELSE convert(nvarchar(10),syc.max_length) end + ');'
FROM sys.objects syo
JOIN sys.columns syc ON
syc.object_id= syo.object_id
JOIN sys.types syt ON
syt.system_type_id = syc.system_type_id
JOIN sys.schemas sysc ON
syo.schema_id=sysc.schema_id
WHERE
syt.name = 'varchar'
and syo.type='U'
4
Das Problem mit Antwort Josefs ist, dass es NOT NULL
Felder NULL
nach der Ausführung der Abfragen ändern würde. Die folgende Manipulation behebt es:
SELECT cmd = 'alter table [' + c.table_schema + '].[' + c.table_name
+ '] alter column [' + c.column_name + '] nvarchar('
+CASE WHEN CHARACTER_MAXIMUM_LENGTH<=4000
THEN CAST(CHARACTER_MAXIMUM_LENGTH as varchar(10)) ELSE 'max' END+')'
+ CASE WHEN IS_NULLABLE='NO' THEN ' NOT NULL' ELSE '' END,*
FROM information_schema.columns c
WHERE c.data_type='varchar'
ORDER BY CHARACTER_MAXIMUM_LENGTH desc
Credits Igor's answer
Dieses schön für mich gearbeitet. Tolles kleines Skript! – DanM
Seien Sie vorsichtig damit, weil Sie alle Standardwerte für eine neue Spalte erhalten. Z. B. wird ein Nicht-Null-Varchar als Nullable-Nvarchar erzeugt. –