1

最初はpartner_email、タイプが。の列()がありvarcharます。最近の変更により、データ型に変更するために変更する必要がありますXMLが、既存の行を新しい列に変換する必要があります。

必要なヘルプ

4

1 に答える 1

1

スクリプトをステップスルーすると、問題を理解するのに役立ちます。

スクリプト1

  1. テストデータベースを使用する
  2. partner_email_tempがPartnerテーブルに存在しない場合はpartner_email_temp、XML列として追加します
  3. パートナーテーブルを更新します。の値をpartner_email_tempXML対応の文字列バージョンに変更しますpartner_email。次に、それをXMLに変換します。REPLACEを使用して、すべての&をエンコードされた&ampに変換します
  4. partner_emailパートナーから列を削除します
  5. 列の名前を次のように変更しpartner_email_tempますpartner_email

これはすべて初めて機能します。スクリプトを2回実行すると、SQL Serverはステップ2に進み、ALTERTABLEステートメントを再度実行します。これは、列partner_email_tempが存在しないためです(最初の実行でpartner_emailに名前が変更されました)。

partner_emailここで、ステップ3で、列を再度更新しようとしています。問題は、この列がXMLデータ型になり、使用REPLACEが違法になることです。そのため、SQLServerはエラーをスローします。

スクリプト2

  1. partner_emailPartnerの列の列データ型をキャプチャします。
  2. 列のデータ型がvarcharの場合(これはスクリプトの最初のパスであることを意味します)、BEGINとENDでコードを実行します
  3. partner_email_tempが存在しない場合は、 partner_email_temp列をXMLとして追加します
  4. partner_email_temp の値をXMLに適した文字列バージョンに変更してPartnerテーブルを更新してから、XMLpartner_emailに変換します。REPLACEすべての&をエンコードされた&ampに変換するために使用します
  5. partner_emailパートナーから列を削除します
  6. 列の名前を次のように変更しpartner_email_tempますpartner_email

GO2番目のスクリプトの問題は、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, ''&'', ''&amp;'') 
  + ''</Email><Email></Email><Email></Email></PartnerEmails>'';
  ALTER TABLE Partner ALTER Column partner_email XML
  '

  EXEC (@sqlCmd) 

END
于 2012-06-10T03:45:47.770 に答える