1

こんなお願いがあります

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES)
SELECT CLIENT_ID, 160 AS TYPE_DONNEES
FROM    REFERENTIEL r, CLIENT_APPLICATIF ca
WHERE r.ID = ca.ID_REFERENTIEL
AND r.TYPE=1
GROUP BY CLIENT_ID
HAVING COUNT(*)>0;

何度か実行すると、データを数回挿入しましたが、データを一度だけ挿入したリクエストを希望します。テーブルにデータが存在しない場合は、データを挿入したいと思います。

4

4 に答える 4

3

できるよ:

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES)
SELECT CLIENT_ID, 160 AS TYPE_DONNEES
FROM    REFERENTIEL r, CLIENT_APPLICATIF ca
WHERE r.ID = ca.ID_REFERENTIEL
AND r.TYPE=1
AND NOT EXISTS (
    SELECT * FROM SERVICEPAYANT_CLIENT sp
    WHERE sp.RE_ID = CLIENT_ID AND TYPE_DONNEES = 160)
GROUP BY CLIENT_ID
HAVING COUNT(*)>0;

「AND NOT EXISTS...」は、ターゲット テーブルにまだ存在しない行を返すように制限するものです。

于 2012-04-26T14:11:53.150 に答える
2

MERGEこれらのケースについては、いくつかの成熟した DBMS に 文があります。同時にMERGEです。INSERTUPDATE

一般的な構文例:

     MERGE INTO TABLE_NAME USING table_reference ON (condition)
       WHEN MATCHED THEN
       UPDATE SET column1 = value1 [, column2 = value2 ...]
       WHEN NOT MATCHED THEN
       INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ...

MySQL のような一部の DBMS には、同じ考え方を持つ独自の構文があります。ウィキペディアで詳細を参照してください。

DBMS がそれをサポートしない場合は、同じロジックでストアド プロシージャを作成できます。

しかし、ストアド プロシージャまたは挿入前のコード内のその他の種類のチェックにより、「ラグ」が発生し、操作が「非アトミック」になります。これは、チェックの直後で挿入の前に、別のトランザクションが重複レコードを作成し、予期しない重複または例外が発生する可能性があることを意味します。これを回避するには、この操作の前にテーブルをロックして、テーブルへの排他的アクセスを取得する必要があります。これには、アクセスのシリアライゼーションによるポーフォマンス ペナルティがあります。

INSERTまたは、次のSELECTように使用できます。

    INSERT (field1, ...) INTO table1
    SELECT value1, ...
    FROM DUAL -- put a name of analogue of Oracle's DUAL here
    WHERE NOT EXISTS (
       SELECT 1 
       FROM table1
       WHERE key = :new_key
    )

しかし、ご理解のとおり、何も更新されません。

于 2012-04-26T14:16:33.910 に答える
1

典型的な解決策は、レコードを定義するフィールドで構成される一意の制約をデータベースに適用することです。Java コードはデータベースからエラーを返し、それが既に存在することを知らせます。

于 2012-04-26T14:10:52.870 に答える
1

あなたはこれを行うことができます:

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES)
SELECT CLIENT_ID, 160 AS TYPE_DONNEES
REFERENTIEL r
JOIN CLIENT_APPLICATIF ca
    ON r.ID = ca.ID_REFERENTIEL
WHERE 
    r.TYPE=1
    AND NOT EXISTS
        (
            SELECT
                NULL
            FROM
                SERVICEPAYANT_CLIENT
            WHERE
                REFERENTIEL.CLIENT_ID=SERVICEPAYANT_CLIENT.RE_ID
        )
GROUP BY CLIENT_ID
HAVING COUNT(*)>0;
于 2012-04-26T14:12:30.010 に答える