web-dev-qa-db-ja.com

リンクサーバー経由でデータをコピー中にエラーが発生しました

リンクサーバーを介して、1つのテーブルの内容を1つのデータベースから別のデータベースにコピーしようとしています。

そのために次のクエリを使用しています

_insert into [Schema].[Table] select * from [Server].[Database].[SCHEMA].[Table]
_

クエリは次のエラーで失敗します。

リンクサーバー 'ServerName'のOLE DBプロバイダー 'SQLNCLI11'は、列 '[Server]。[DATABASE]。[SCHEMA]。[TABLE] .GDTXVC'に無効なデータを返しました。

列名をリストした場合も同じエラーが発生しますが、300万行以上のテーブルであるため、_select *_を単独で試しませんでした。

テーブルが両方のデータベースで同じであることを確認しました。エラーで報告されている列は両方のテーブルでTEXTデータ型であり、列は両方でNULLを受け入れます同じように。

除外するために、問題のテーブルに対してDBCC CHECKTABLE() with data_purityを実行しましたが、エラーも返されませんでした。何が欠けているのか、どこを見ればよいのかわかりません。

ローカルテーブル-宛先

_    CREATE TABLE [CRPDTA].[F00165](
    [GDOBNM] [char](10) NOT NULL,
    [GDTXKY] [varchar](254) NOT NULL,
    [GDLNGP] [char](2) NOT NULL,
    [GDTXPO] [varchar](254) NULL,
    [GDCRTU] [char](10) NULL,
    [GDDQE] [numeric](18, 0) NULL,
    [GDTENT] [float] NULL,
    [GDMUSE] [char](10) NULL,
    [GDUPMJ] [numeric](18, 0) NULL,
    [GDTDAY] [float] NULL,
    [GDEFTJ] [numeric](18, 0) NULL,
    [GDEXDJ] [numeric](18, 0) NULL,
    [GDPNTC] [char](1) NULL,
    [GDISTM] [char](1) NULL,
    [GDISFL] [char](1) NULL,
    [GDTXTL] [float] NULL,
    [GDIMGL] [float] NULL,
    [GDOLEL] [float] NULL,
    [GDMSCL] [float] NULL,
    [GDFUTL] [float] NULL,
    [GDTXVC] [text] NULL,
 CONSTRAINT [F00165_PK] PRIMARY KEY CLUSTERED 
(
    [GDOBNM] ASC,
    [GDTXKY] ASC,
    [GDLNGP] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
_

リモートサーバー-ソーステーブル

_CREATE TABLE [PRODDTA].[F00165](
    [GDOBNM] [char](10) NOT NULL,
    [GDTXKY] [varchar](254) NOT NULL,
    [GDLNGP] [char](2) NOT NULL,
    [GDTXPO] [varchar](254) NULL,
    [GDCRTU] [char](10) NULL,
    [GDDQE] [numeric](18, 0) NULL,
    [GDTENT] [float] NULL,
    [GDMUSE] [char](10) NULL,
    [GDUPMJ] [numeric](18, 0) NULL,
    [GDTDAY] [float] NULL,
    [GDEFTJ] [numeric](18, 0) NULL,
    [GDEXDJ] [numeric](18, 0) NULL,
    [GDPNTC] [char](1) NULL,
    [GDISTM] [char](1) NULL,
    [GDISFL] [char](1) NULL,
    [GDTXTL] [float] NULL,
    [GDIMGL] [float] NULL,
    [GDOLEL] [float] NULL,
    [GDMSCL] [float] NULL,
    [GDFUTL] [float] NULL,
    [GDTXVC] [text] NULL,
 CONSTRAINT [F00165_PK] PRIMARY KEY CLUSTERED 
(
    [GDOBNM] ASC,
    [GDTXKY] ASC,
    [GDLNGP] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
_

リンクサーバーの定義

_EXEC master.dbo.sp_addlinkedserver @server = N'<SERVERNAME>', @srvproduct=N'SQL Server'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'<SERVERNAME>',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'collation compatible', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'data access', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'dist', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'pub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'rpc', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'rpc out', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'sub', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'connect timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'collation name', @optvalue=null
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'lazy schema validation', @optvalue=N'false'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'query timeout', @optvalue=N'0'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'use remote collation', @optvalue=N'true'
EXEC master.dbo.sp_serveroption @server=N'<SERVERNAME>', @optname=N'remote proc transaction promotion', @optvalue=N'true'
_

リンクは問題ないようです。このリンクを介して他の複数のテーブルデータをコピーできたので、問題はテーブルまたはおそらくその中のデータに限定されていると確信しています。

データをコピーしようとしたデータベースのコピーが2つあります。1つは本番(SQL Server 2005)、もう1つは開発サーバー(2008)に復元したコピーです。 SQL Server 2012サーバーにデータを書き込もうとしています。テーブル定義はアプリケーションで生成されたものであり、どちらの側でも変更できません。

照合:

両方のデータベースには、Chinese_PRC_CI_ASの照合順序があり、列にも両方のデータベースのChinese_PRC_CI_AS照合順序があります。

2つのデータベース間ですべてが一致している必要があります。新しいDBは、ソースデータベースのバックアップを復元することによって作成されました。復元が数か月前に行われたため、ソースデータベースが古くなっているため、現在、dblinkを介してデータを移動しています。環境を同期させるために、必要に応じてデータを移動しています。

ウィンドウズ

サーバーは同じバージョンのWindowsを実行していません。ソースはWindows 2003(32ビット)を実行しており、宛先はWindows 2012を実行しています。データを個別のクエリに分割するのに十分な知識がないため、移行のためにすべてのデータを移動する必要があります。行う。

テストクエリ

次のクエリはすべてエラーなしで正しく機能しました

_SELECT TOP (1) [GDTXVC] from <SERVER>.<DATABASE>.<SCHEMA>.F00165;
SELECT TOP (1) [GDTXKY] FROM <SERVER>.<DATABASE>.<SCHEMA>.F00165;
INSERT INTO <SCHEMA>.F00165 ([GDOBNM], [GDTXKY], [GDLNGP], [GDTXVC]) SELECT TOP (1) [GDOBNM], [GDTXKY], [GDLNGP], [GDTXVC] FROM <SERVER>.<DATABASE>.<SCHEMA>.F00165;
_

また、Microsoft Premierサポートでケースをオープンしました。Microsoftで行ったトラブルシューティングの手順と、彼らが持っている/提案する可能性のあるすべてのソリューションを使用して、この質問を最新の状態に保ちます。

4
Patrick

問題は、関連するさまざまなWindows OSバージョンでの Code Page 936 の異なる実装に起因している可能性があります。

bcpユーティリティ-Nオプションとともに使用して、ファイルを介してデータを一括でエクスポートおよびインポートすることをお勧めします。

-Nオプション:

非文字データの場合はデータのネイティブ(データベース)データ型を使用し、文字データの場合はUnicode文字を使用して一括コピー操作を実行します。

製品ドキュメントの nicode Native Format to Import or Export Data(SQL Server) を参照してください。

Unicodeネイティブ形式は、Microsoft SQL Serverインストール間で情報をコピーする必要がある場合に役立ちます。文字以外のデータにネイティブ形式を使用すると、時間を節約でき、データ型と文字形式の間の不要な変換が不要になります。すべての文字データにUnicode文字形式を使用することで、異なるコードページを使用するサーバー間でデータを一括転送するときに、拡張文字が失われるのを防ぎます。 Unicodeネイティブ形式のデータファイルは、任意の一括インポートメソッドで読み取ることができます。

ローカル2008および2012インスタンスでこのメソッドをテストするために使用したコマンドラインの例:

-- Export data to file
bcp Sandpit.dbo.Test out c:\temp\test.bcp -N -S .\SQL2K8 -T

-- Import data from file
bcp Sandpit.dbo.Test in c:\temp\test.bcp -N -S .\SQL2012 -T

最高のパフォーマンスを得るには、 一括インポートでの最小限のログ記録の前提条件 を満たしていることを確認してください。

3
Paul White 9

猫の皮をむく方法はたくさんあります!

LinkedServerが設定されているので、 OPENQUERY() の使用を検討してください。

例えば:

SELECT INTO targetDB.dbo.myTable FROM OPENQUERY(myLinkedServer, "SELECT * FROM anotherTable)

テーブルがターゲットデータベース(intoにコピーしているデータベース)に存在しない場合、上記の1行でテーブルが作成されます君は。実際、データベースが別のサーバーを介してコピーを確実に処理できるように、この方法で実行することをお勧めします。

しかし、私はあなたのLinked Serverを最初にテストして、それが機能していることを確認します:

SELECT * FROM OPENQUERY(linkedserver, "SELECT * FROM table")
0
Fandango68