1

Accessに「tempSpring_ASN」というテーブルがあり、次のフィールドがあります(特に)。

SHP_CUSTOM_5(オートナンバー)

RECORD_TYPE(テキスト)

PO_NUM(テキスト)。

RECORD_TYPEの値を変更する必要があります。たとえば、PO_NUMが前のレコードのPO_NUMと同じである場合、RECORD_TYPEは「LIN」である必要があります。それ以外の場合(または最初のレコードである場合)、RECORD_TYPEは「HDR」である必要があります。

RECORD_TYPEの正しい新しい値を取得するために、次のクエリを作成しました。

SELECT TOP 1 t1.SHP_CUSTOM_5,
    t1.PO_NUM AS CurrentValue,
    NULL AS PreviousValue,
    "HDR" AS RECORD_TYPE
FROM tempSpring_ASN AS t1
ORDER BY t1.SHP_CUSTOM_5
UNION ALL
SELECT t1.SHP_CUSTOM_5,
    t1.PO_NUM AS CurrentValue,
    t2.PO_NUM AS PreviousValue,
    IIf([CurrentValue]=[PreviousValue],'LIN','HDR') AS RECORD_TYPE
FROM tempSpring_ASN AS t1,
    tempSpring_ASN AS t2
WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
ORDER BY t1.SHP_CUSTOM_5;

そのクエリを「tempSpring_ASN_With_PreviousRow」として保存しました。今、私はそれを使用して、次のクエリで元のtempSpring_ASNテーブルを更新しようとしています。

UPDATE tempSpring_ASN INNER JOIN tempSpring_ASN_With_PreviousRow ON tempSpring_ASN.SHP_CUSTOM_5 = tempSpring_ASN_With_PreviousRow.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = [tempSpring_ASN_With_PreviousRow].[RECORD_TYPE];

しかし、「操作は更新可能なクエリを使用する必要があります」というメッセージが表示されます。結合内の1つのテーブルを更新しようとしているのか、同じテーブルの値に基づいてテーブルを更新しようとしているのか、それとも他の理由によるのかはわかりません。とにかく、私はうまくいくものを探しています。

ありがとう!

更新(しゃれは意図されていません)

次の更新クエリを試しました。

UPDATE tempSpring_ASN INNER JOIN Table5 ON tempSpring_ASN.SHP_CUSTOM_5 = Table5.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = "zzz";

そしてそれはうまくいきました。その結果、tempSpring_ASNは更新されましたが、Table5は更新されませんでした。明らかに、SQLステートメントで2つのテーブルが結合されている場合、一方のテーブルで更新を実行しても、結合でもう一方のテーブルを更新しようとはしません。その場合、元の更新クエリが機能しない理由がわかりません。UNIONクエリであるため、tempSpring_ASN_With_PreviousRowは更新できないことは知っていますが、更新しようとはしていません。むしろ、tempSpring_ASN(更新可能な結合内の他のテーブル)を更新しようとしています

更新2: 次に、次のように相関サブクエリを使用してみました。

UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
        SELECT RECORD_TYPE
        FROM (
            SELECT TOP 1 t1.SHP_CUSTOM_5,
                t1.PO_NUM AS CurrentValue,
                NULL AS PreviousValue,
                "HDR" AS RECORD_TYPE
            FROM tempSpring_ASN AS t1
            ORDER BY t1.SHP_CUSTOM_5
            UNION ALL
            SELECT t1.SHP_CUSTOM_5,
                t1.PO_NUM AS CurrentValue,
                t2.PO_NUM AS PreviousValue,
                IIf([CurrentValue] = [PreviousValue], 'LIN', 'HDR') AS RECORD_TYPE
            FROM tempSpring_ASN AS t1,
                tempSpring_ASN AS t2
            WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
            ORDER BY t1.SHP_CUSTOM_5
            )
        WHERE SHP_CUSTOM_5 = t.SHP_CUSTOM_5
        );

しかし、「操作には更新可能なクエリを使用する必要があります」というメッセージが表示されます。

アップデート3:

このエラーは、ユニオンクエリを使用していることが原因であると考えています。問題を特定するために、次のことを試しました(希望する結果は得られませんが、問題の診断には役立ちます)。

UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
        SELECT TOP 1 RECORD_TYPE
        FROM tempSpring_ASN_With_PreviousRow
        );

それは私に同じエラーを与えました。したがって、問題は、ユニオンクエリの出力の単一の値を使用してレコードセットに値を設定できないのはなぜかということです。

4

1 に答える 1

1

私もあなたの新しい質問の中にこの答えを投稿しました。

こんにちはAYS、

Accessでは、更新クエリをテーブルで実行する必要があります。UNIONクエリは複数のレコードセットの組み合わせであるため、結果セットはテーブルではなくなり、結果セット内のレコードが特定のテーブルで一意に識別されなくなるため、更新クエリのオブジェクトにすることはできません。理論的にはそうなる可能性がある場合)。アクセスは、すべてのUNIONクエリを読み取り専用として処理するようにハードコーディングされています。これは、基になるテーブルが複数ある場合に意味があります。この条件をトリガーする他の条件(SELECTステートメントのサブクエリなど)がいくつかあります。

このように考えてみてください。TOP1を使用しておらず、UNIONクエリが複数の結果を返した場合、JETはどの結果をテーブル内の一意のレコードに適用するかをどのように知るのでしょうか。そのため、JETはそのようなすべてのケースを同じように扱います。

残念ながら、これは、すべてのデータが同じテーブルから派生している場合でも当てはまります。この場合、JETオプティマイザーは、これが事実であることを認識し、UNIONを使用しない方法でクエリを言い換えるほど賢くない可能性があります。

この場合でも、すべてがベーステーブルを参照するようにクエリを再記述することで、必要なものを取得できます。たとえば、次をSELECTクエリとして使用して、前のSHP_CUSTOM_5レコードのPO_NUM値を取得できます。

SELECT
t1.SHP_CUSTOM_5
, t1.PO_NUM
, t1.SHP_CUSTOM_5 -1 AS PREV_RECORD

, (SELECT
t2.PO_NUM
FROM
tempSpring_ASN As t2
WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
) AS PREV_PO

FROM
tempSpring_ASN AS t1
;

次に、「LIN」更新を実行するために、これを更新クエリとして次のように表現できます。

UPDATE
tempSpring_ASN AS t1 

SET 
t1.RECORD_TYPE = "LIN"

WHERE
t1.PO_NUM=

(
SELECT 
t2.PO_NUM

FROM
tempSpring_ASN As t2

WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
)
;

このコードは、ダミーデータを使用して実行したテストで成功しました。

「HDR」アップデートに関しては、実際には2つの別々のアップデートを実行しています。1)PO_NUMが前のレコードのPO_NUMと一致する場合は、RECORD_TYPEを「LIN」に設定します。2)それが最初のレコードである場合は、RECORD_TYPEを「HDR」に設定します。

1つのクエリ内でこれらのアクションを実行することに利点がある理由は私にはわかりません。元のSELECTクエリの例で使用した「TOP1」bySHP_CUSTOM_5メソッドを使用してHDR更新を実行することをお勧めします。これは、比較的単純なUPDATEクエリになるためです。Updateクエリ内でIIF()を使用することは可能ですが、必要となる追加の時間と複​​雑さからどのような追加のメリットが得られるかわかりません(ほとんどの場合、読みにくくなるだけです)。

頑張ってください!

于 2013-02-14T23:50:35.623 に答える