最初はpartner_email、タイプが。の列()がありvarcharます。最近の変更により、データ型に変更するために変更する必要がありますXMLが、既存の行を新しい列に変換する必要があります。
必要なヘルプ
最初はpartner_email、タイプが。の列()がありvarcharます。最近の変更により、データ型に変更するために変更する必要がありますXMLが、既存の行を新しい列に変換する必要があります。
必要なヘルプ
スクリプトをステップスルーすると、問題を理解するのに役立ちます。
スクリプト1
partner_email_tempがPartnerテーブルに存在しない場合はpartner_email_temp、XML列として追加しますpartner_email_tempXML対応の文字列バージョンに変更しますpartner_email。次に、それをXMLに変換します。REPLACEを使用して、すべての&をエンコードされた&ampに変換しますpartner_emailパートナーから列を削除しますpartner_email_tempますpartner_emailこれはすべて初めて機能します。スクリプトを2回実行すると、SQL Serverはステップ2に進み、ALTERTABLEステートメントを再度実行します。これは、列partner_email_tempが存在しないためです(最初の実行でpartner_emailに名前が変更されました)。
partner_emailここで、ステップ3で、列を再度更新しようとしています。問題は、この列がXMLデータ型になり、使用REPLACEが違法になることです。そのため、SQLServerはエラーをスローします。
スクリプト2
partner_emailPartnerの列の列データ型をキャプチャします。partner_email_tempが存在しない場合は、
partner_email_temp列をXMLとして追加しますpartner_email_temp
の値をXMLに適した文字列バージョンに変更してPartnerテーブルを更新してから、XMLpartner_emailに変換します。REPLACEすべての&をエンコードされた&ampに変換するために使用しますpartner_emailパートナーから列を削除しますpartner_email_tempますpartner_emailGO2番目のスクリプトの問題は、BEGINステートメントとENDステートメントでステートメントを使用できないことです。
BOLによると:
SQL Serverユーティリティは、GOを、Transact-SQLステートメントの現在のバッチをSQLServerのインスタンスに送信する必要があるというシグナルとして解釈します。
partner_email_tempしたがって、スクリプト2では、SQL Serverがコンパイルを試みると、列が存在しないことに気付きます。セクションが個別に実行されるため、スクリプト1で機能します。そして、参照する部分partner_email_tempが実行されるとき、列は存在します。
では、どのように修正しますか?
partner_email列のデータを正しい形式に更新してから、列をXMLデータ型に変換するだけで、実際には列の削除と名前変更をすべてバイパスできます。これは1つのSQLバッチステートメントで実現できますが、SQL Serverがvarcharデータ型のREPLACE場合にのみステートメントを実行しようとするように、動的SQLとして実行する必要があります。partner_email column
IF NOT EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.columns
WHERE table_name = 'Partner'
AND column_name = 'partner_email'
AND data_type = 'xml'
)
BEGIN
DECLARE @sqlCmd NVARCHAR(4000)
SET @sqlCmd = N'
UPDATE [dbo].[Partner]
SET partner_email = ''<PartnerEmails><Email>''
+ REPLACE(partner_email, ''&'', ''&'')
+ ''</Email><Email></Email><Email></Email></PartnerEmails>'';
ALTER TABLE Partner ALTER Column partner_email XML
'
EXEC (@sqlCmd)
END