2

UNPIVOT別のデータベースのテーブルで、ストアド プロシージャからステートメントを実行しようとしています。ローカルで罰金を実行できますがUNPIVOT、別のデータベース/サーバーで実行すると、次のエラーが発生します。

The type of column "XXX" conflicts with the type of other columns specified in the UNPIVOT list.

これは、私の のスリム化されたバージョンですUNPIVOT

CREATE TABLE temp (
  id nvarchar(100),
  F1 nvarchar(100),
  F2 nvarchar(100),
  F3 decimal(5,0)
)

INSERT INTO temp VALUES(N'100', N'111', N'AAA', 123)
INSERT INTO temp VALUES(N'100', N'222', N'BBB', 456)
INSERT INTO temp VALUES(N'100', N'333', N'CCC', 789) 
INSERT INTO temp VALUES(N'100', N'444', N'DDD', 012)
INSERT INTO temp VALUES(N'100', N'555', N'EEE', 345)

SELECT * FROM (   SELECT
    ID,
    CAST(F1 AS NVARCHAR(MAX)) AS F1,--used in order to normalize the data
    CAST(F2 AS NVARCHAR(MAX)) AS F2,--used in order to normalize the data
    CAST(F3 AS NVARCHAR(MAX)) AS F3--used in order to normalize the data
FROM
    TEMP   ) AS T UNPIVOT(FieldValue for FieldName in (   F1, F2, F3   )) AS UNPVT

SQL フィドル

このエラーは、私が使用しているテーブルにフィールド タイプがある場合に発生することに気付きましUNPIVOTDECIMAL()

いつものように、どんな助けも大歓迎です。


更新: リモート サーバーでビューを作成すると、問題CASTが適切に発生するようになります。しかし、なぜ?も使用してみcteましたが、うまくいきませんでした。ビューの作成を避けたかったのです。うまくいけば、それが唯一の解決策ではありません。

4

1 に答える 1

4

エラー

列「XXX」のタイプは、UNPIVOT リストで指定された他の列のタイプと競合しています。

非常に明白で、より良いメッセージの 1 つです。UNPIVOT リストにさまざまなタイプの列が含まれていることがわかります。このようなエラーの原因となる例を次に示します: SQL Fiddle

SELECT * FROM (
  SELECT
    ID,
    CAST(F1 AS NVARCHAR(MAX)) AS F1,
    CAST(F2 AS NVARCHAR(MAX)) AS F2,
    F3  -- note F3 is a decimal column containing decimal values
  FROM
    TEMP
  ) AS T
UNPIVOT(FieldValue for FieldName in (
  F1, F2, F3  -- F3 type is different from F1/F2
  )) AS UNPVT

ローカル クエリでは、質問 SQL Fiddle に記述されているクエリを考えると、すべての列を既に NVARCHAR(MAX) として CAST しているため、このエラーが発生する可能性はありません。

ただし、リモート クエリでは、コンパイル時に SQL Server がクエリに失敗したように見えます。CAST の前にピボット列を事前に検証しているようです。これは、実行フローの別の時点で CAST をローカルで実行できる可能性があるためと思われます。これに対する回避策は、リモート サーバー上の CAST を解決する VIEW を作成することです。

回避策

FOR XMLを使用して、クエリをリモートで解決するように強制できます(少なくともリモートサーバーとして2005でテスト済み)。これには、nvarchar(max)とにかく適合のために値が抽出されるという利点があります。

SELECT *
FROM (
    SELECT n.value('ID[1]','nvarchar(max)') ID
          ,n.value('F1[1]','nvarchar(max)') F1
          ,n.value('F2[1]','nvarchar(max)') F2
          ,n.value('F3[1]','nvarchar(max)') F3
    FROM (   
        SELECT (
            SELECT
                ID,
                F1,
                F2,
                F3
            FROM
                [akltrsvrdb\sqllatin].test1.dbo.temp
            FOR XML PATH('a'), type
        ) XmlPacket
    ) x
    cross apply XmlPacket.nodes('/a') n(n)
) T UNPIVOT(FieldValue for FieldName in (   F1, F2, F3   )) AS UNPVT

SQLKiwiは、こちらのチャット トランスクリプトに示されているように、CAST ターゲットとしてsql_variantを使用するとリモート クエリが機能することを発見しました。

SELECT
    *
FROM
    (
        SELECT
            [id],
            CONVERT(sql_variant, [F1]) as F1,
            CONVERT(sql_variant, [F2]) as F2,
            CONVERT(sql_variant, [F3]) as F3,
            CONVERT(sql_variant, CAST([D20] as nvarchar(4000))) as F20--in case the source field is text (Make sure that 4000 is enough characters!)
        FROM
            [server].[database].[scheme].[table]
    ) as t
UNPIVOT(FieldValue for FieldName in ([F1],[F2],[F3],[D20])) as unpvt
于 2012-12-11T20:34:45.480 に答える