簡體   English   中英

如何在 SQL 查詢中輕松將所有 ntext 字段轉換為 nvarchar(max)?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM