Sql-Server

關於隱式轉換的警告

  • May 8, 2020

我有 2 個名稱列的表:

CREATE TABLE Test
(
 TestID int identity primary key clustered
 , Name_Eng nvarchar(50)
 , Name_Nat nvarchar(50)
)

現在我需要一個查詢來使該Name列用 分隔,,如下所示:

   DECLARE @NameColumns NVARCHAR(1024)

           SET @NameColumns = STUFF(
     (SELECT   ',' + 'Test.' + name AS [text()]
      FROM     ( SELECT    c.name
                 FROM      sys.columns c 
                           INNER JOIN sys.tables t ON t.object_id = c.object_id
                 WHERE     t.name = 'Test'
                           AND c.name LIKE 'Name_%'
               ) AS D
               FOR                  XML PATH('') ,
                                        TYPE).value('.[1]', 'VARCHAR(MAX)'), 1, 1,
                                    N'')

select  @NameColumns

但是這個查詢在執行計劃中有一個警告:

隱式轉換警告

有什麼辦法可以消除這個警告嗎?

由於 XML 函式,警告就在那裡value()。第二個參數 tovalue()是您希望將儲存在 XML 中的值轉換為的值。您可能會爭辯說,這實際上不是隱式轉換,而是非常顯式的轉換,因為您要求它發生。可能需要向 Microsoft 建議的連接項目。

重現您所看到的最簡單的方法。

declare @X xml;
select @X.value('text()[1]', 'int');

給出這兩個警告。

<Warnings>
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(int,XML Reader with XPath filter.[lvalue],0)" />
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(int,XML Reader with XPath filter.[value],0)" />
</Warnings>

如您所見,您也可以使用 int 獲得它,並且每次呼叫value().

declare @X xml;
select @X.value('text()[1]', 'int'),
      @X.value('text()[1]', 'bit');
<Warnings>
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(int,XML Reader with XPath filter.[lvalue],0)" />
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(int,XML Reader with XPath filter.[value],0)" />
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(bit,XML Reader with XPath filter.[lvalue],0)" />
   <PlanAffectingConvert ConvertIssue="Cardinality Estimate" Expression="CONVERT_IMPLICIT(bit,XML Reader with XPath filter.[value],0)" />
</Warnings>

轉換是在 Stream Aggregate 運算符中完成的,該運算符計算這樣的值。

MIN(CASE WHEN [@X] IS NULL 
     THEN NULL 
     ELSE 
     CASE WHEN datalength(XML Reader with XPath filter.[value])>=(128) 
       THEN CONVERT_IMPLICIT(int,XML Reader with XPath filter.[lvalue],0) 
       ELSE CONVERT_IMPLICIT(int,XML Reader with XPath filter.[value],0) 
     END 
   END)

表值函式的結果在lvalueorvalue列中返回。該表達式通過使用datalength來檢查它應該從哪裡獲取,然後將其轉換為您想要的數據類型。

有什麼辦法可以消除這個警告嗎?

就在這裡。從語句中刪除TYPE指令FOR XML PATH並刪除對value()函式的呼叫。這樣做的一個副作用是,您連接的包含需要在 XML 中編碼的字元的值&<>將被編碼到您的結果中。

引用自:https://dba.stackexchange.com/questions/126632