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 中 有一句话就是针对这些情况的。MERGEINSERTUPDATE同时。

一般语法示例:

     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 回答