1

更新ステートメント内に挿入ステートメントをネストすることは可能ですか?

背景:

mergeこの句を初めて使用して、一部のデータを変換しています。つまり、多くの列を持つ単一のソース テーブルがありますが、より適切な言葉がない場合は、より構造化されたモデル/スキーマに変換する必要があります。モデルのそれに似ていBIます。また、BI モデリングの経験もありません (読み始めてから 1 か月も経っていません)。どんな助けでも大歓迎です。

支援に必要なその他の情報があれば喜んで提供します。

エラー:

メッセージ 156、レベル 15、状態 1、行 47
キーワード「select」付近の構文が正しくありません。

メッセージ 102、レベル 15、状態 1、行 48
')' 付近の構文が正しくありません。

これらは、tertiary.WEBADDRESS行に挿入しようとした時点でスローされます。

コード:

--Transform operation
--web address dimension insert
use UniversityUS
merge tertiary.INSTITUTION as target
using(
        select UNITID,
             INSTNM,
             ADDR,
             CITY,
             STABBR,
             ZIP,
             OBEREG,
             WEBADDR,
             ADMINURL,
             FAIDURL,
             APPLURL,
             HLOFFER,
             GENTELE,
             LOCALE,
             CARNEGIE,
             FAXTELE,
             IALIAS,
             F1SYSNAM,
             COUNTYNM,
             LONGITUD,
             LATITUDE
             --geography::Point(LATITUDE,LONGITUD,4326)) as [LOCATION]
        from staging.secondary_university
        where closedat = -2
    ) as source
on ( source.UNITID = target.ROWSOURCECONTROLID )
when not matched by target then

        --this would represent my fact table
        insert (INSTNM,IALIAS,GENTELE,F1SYSNAM,ROWSOURCECONTROLID)
        values (source.INSTNM,source.IALIAS,source.GENTELE,source.F1SYSNAM,source.UNITID)       

when matched then

        update set target._WEBADDRID = 
        (
            select wa.wid
            from
            (
                --this would represent one of my many dimension tables
                --if i comment the next two lines it works
                --but i need to know how will these be updated.
                insert into tertiary.WEBADDRESS 
                values(source.WEBADDR,source.ADMINURL,source.FAIDURL,source.APPLURL)

                select scope_identity() as wid
            )wa 
        )

when not matched by source then
    delete
output $action;
4

1 に答える 1

2

これは古い質問であることは承知していますが、興味深い質問なので、自分の好奇心を調査しているときに偶然出くわす可能性のある人のために、できる限り答えます.

これはおそらく悪い習慣であると言って始めましょう。このようなステートメントを入れ子にしようとすると、コードが読めなくなる危険性があります。同時実行性の問題が発生したとしても、それほど驚くことではありません。ただし、これに完全に納得している場合は、おそらくストアド プロシージャを使用して同様のことを達成できます。しかし、繰り返しになりますが、そのような不明確な副作用があるものは、おそらく判読できません。OUTPUTまた、その挿入の句を調べることもできます。OUTPUT INSERTED.IDよくわかりませんが、挿入に続いて選択を利用するのではなく、(またはID列の名前が何であれ)追加して、それに対して選択を実行できることは理にかなっています。繰り返しますが、それが機能するかどうかはわかりません。しかし、それは合理的に聞こえます。

とはいえ、アーロンが彼のコメントでほのめかしたように見えるので、これをいくつかの別々の操作に分けたほうがよいでしょう。私は個人的MERGEには問題ありません.少なくとも、トランザクションを共有する別のステートメントに挿入を引き出すことをお勧めします。

INSERT INTO tertiary.WEBADDRESS 
SELECT WEBADDR, ADMINURL, FAIDURL, APPLURL
    FROM staging.secondary_university
    WHERE closedat = -2 AND
          EXISTS (SELECT *
                  FROM tertiary.INSTITUTION
                  WHERE tertiary.Institution.ROWSOURCECONTROLID = staging.secondary_university.UNITID)

次に、句を簡単に変更して、WHEN MATCHED一意性を確立するために必要なキーがあれば、適切な ID 値を取得できます。

 ...
 WHEN MATCHED THEN
      UPDATE SET target._WEBADDRID = (SELECT TOP 1 [whatever_your_ID_column_is]
                                      FROM staging.secondary_university
                                      WHERE staging.secondary_university.WebAddr = source.WebAddr AND
                                            staging.secondary_university.ADMINURL = source.ADMINURL AND
                                            staging.secondary_university.FAIDURL = source.FAIDURL AND
                                            staging.secondary_university.APPLURL = source.APPLURL)
 ...
于 2014-07-06T07:57:11.037 に答える