[英]How can I easily convert all ntext fields to nvarchar(max) in SQL query?
我希望能夠編寫 SQL 查詢,而無需枚舉列,這將返回所有列,以及轉換為 varchar(max) 的任何 ntext 列。 我想知道是否有一種聰明的方法來做到這一點。
這會很棒,因為這樣我就可以對此類查詢執行基於比較的運算符,例如 UNION、EXCEPT 等。 netxt 列不可比較,因此在使用這些運算符時會失敗。
我目前的想法:
創建一個函數以將查詢構建為動態 sql。 類似的東西: http : //lotsacode.wordpress.com/2010/03/23/sql-server-ntext-cannot-be-selected-as-distinct/
有沒有更好的辦法?
感謝您的輸入!
無論如何, NTEXT
將從 SQl-Server 的未來版本中刪除(連同 Image 和 text ),那么為什么不硬着頭皮將列更改為NVARCHAR(MAX)
呢? 一次可能會很昂貴,但它可能是值得的:
ALTER TABLE dbo.T ALTER COLUMN NTextColumn NVARCHAR(MAX) NULL; -- OR NOT NULL
您可以使用以下命令為整個數據庫生成和執行腳本:
DECLARE @SQL NVARCHAR(MAX) =
( SELECT 'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' +
QUOTENAME(OBJECT_NAME(object_id)) +
' ALTER COLUMN ' + QUOTENAME(Name) +
' NVARCHAR(MAX) ' +
CASE WHEN is_nullable = 0 THEN 'NOT' ELSE '' END +
' NULL;' + CHAR(13) + 'GO' + CHAR(13)
FROM sys.columns
WHERE system_type_id = 99 --NTEXT
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)');
EXECUTE sp_executesql @SQL;
我使用了這個光標(在這里,恐怕沒有基於集合的替代方案)來做到這一點:
DECLARE TableCursor CURSOR FAST_FORWARD
FOR
SELECT
t.Name,
c.name,
c.is_nullable,
typ.user_type_id
FROM
sys.columns c
INNER JOIN
sys.tables t ON c.object_id = t.object_id
INNER JOIN
sys.types typ ON c.system_type_id = typ.system_type_id
WHERE
typ.name IN ('text', 'ntext') -- user_type_id: text = 35, ntext = 99
DECLARE @TableName sysname, @ColumnName sysname, @IsNullable BIT, @TypeID INT
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO @TableName, @ColumnName, @IsNullable, @TypeID
WHILE @@FETCH_STATUS = 0
BEGIN
DECLARE @Stmt NVARCHAR(999)
SET @Stmt = 'ALTER TABLE dbo.[' + @TableName + '] ALTER COLUMN [' + @ColumnName + '] ' +
CASE @TypeID
WHEN 35 THEN ' VARCHAR(MAX) '
WHEN 99 THEN ' NVARCHAR(MAX) '
END +
CASE WHEN @IsNullable = 1 THEN 'NULL' ELSE 'NOT NULL' END
PRINT @Stmt
EXEC (@Stmt)
FETCH NEXT FROM TableCursor INTO @TableName, @ColumnName, @IsNullable, @TypeID
END
CLOSE TableCursor
DEALLOCATE TableCursor
我假設我的所有表都在dbo
架構中,從而稍微簡化了我的代碼 - 如果您不是這種情況,則您也必須包括來自sys.schema
目錄視圖的架構。
運行此代碼將一勞永逸地將所有text
轉換為varchar(max)
並將所有ntext
轉換為nvarchar(max)
,並且您與text/ntext
所有問題都將一去不復返了! :-)
這是我對上面 GarethD 回答的修改版本。 SQL 無法找到某些表時出現問題,因此我使用了 sys.tables 與 sys.columns 連接。 此外,is_nullable 行不正確(如果該字段不可為空,則將其設置為 NOT NULL)。
DECLARE @SQL NVARCHAR(MAX) = ' ';
SELECT @SQL = @SQL + ' ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(sys.columns.object_id)) + '.' +
QUOTENAME(OBJECT_NAME(sys.columns.object_id)) +
' ALTER COLUMN ' + QUOTENAME(sys.columns.Name) +
' NVARCHAR(MAX) ' +
CASE WHEN is_nullable = 0 THEN 'NOT NULL' ELSE '' END
FROM sys.Tables
inner join sys.columns on sys.tables.object_id = sys.columns.object_id
WHERE sys.columns.system_type_id = 99 ; --NTEXT
EXECUTE sp_executesql @SQL;
GO
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.