MySQL에서 '존재하지 않는 경우 삽입'을 하려면 어떻게 해야 합니까?
처음에 구글에서 검색했는데, Mutex 테이블에 대해 설명하는 표준 SQL에 INSERT if NOT EXISTES 쿼리를 쓰는 방법 기사를 발견했습니다.
1400만 장에 달하는 음반이 있는 테이블이 있어요같은 형식으로 데이터를 추가할 경우 쿼리 쌍을 사용하지 않고 삽입할 레코드가 존재하지 않는지 확인할 수 있는 방법이 있습니까(확인할 쿼리와 삽입할 쿼리가 각각 비어 있습니다.
는 ㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇㅇ?unique
insert
할까?
PHP를 통해 삽입을 발행하면 제약만으로 스크립트가 끊기는 것 같습니다.
INSERT IGNORE INTO table
.
그리고 또INSERT … ON DUPLICATE KEY UPDATE
구문은 13.2.6.2 INSERT...에 설명되어 있습니다. 중복된 키 업데이트 스테이트먼트.
Google 웹 캐시에 따라 bogdan.org.ua에서 게시:
2007년 10월 18일
처음에: 최신 MySQL에서는 제목에 표시되는 구문을 사용할 수 없습니다.그러나 기존 기능을 사용하여 기대하는 바를 달성하는 방법은 몇 가지 매우 간단합니다.
INSERT IGNORE, REPLACE 또는 INSERT … 키를 중복하여 업데이트할 때 3가지 해결책이 있습니다.
테이블이 있다고 상상해 보세요.
CREATE TABLE `transcripts` ( `ensembl_transcript_id` varchar(20) NOT NULL, `transcript_chrom_start` int(10) unsigned NOT NULL, `transcript_chrom_end` int(10) unsigned NOT NULL, PRIMARY KEY (`ensembl_transcript_id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
이제 Ensubbl에서 스크립트 메타 데이터를 가져오는 자동 파이프라인이 있고 다양한 이유로 인해 실행 단계에서 파이프라인이 고장날 수 있다고 상상해 보십시오.따라서 다음 두 가지를 확인해야 합니다.
- 파이프라인을 반복적으로 실행해도 > 데이터베이스가 파괴되지 않습니다.
- 반복 실행은 'displays > primary key' 오류로 인해 중지되지 않습니다.
방법 1: 치환 사용
매우 간단합니다.
REPLACE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
레코드가 존재하면 덮어쓰고 존재하지 않으면 생성됩니다.다만, 이 방법을 사용하는 것은 효율적이지 않습니다.기존 레코드를 덮어쓸 필요는 없습니다.그냥 건너뛰어도 괜찮습니다.
방법 2: INSERT IGNORE 사용 또한 매우 간단합니다.
INSERT IGNORE INTO `transcripts` SET `ensembl_transcript_id` = 'ENSORGT00000000001', `transcript_chrom_start` = 12345, `transcript_chrom_end` = 12678;
여기서 'ensembl_transcript_id'가 데이터베이스에 이미 있는 경우 자동으로 건너뜁니다(무시).(정확하게는 MySQL 참조 매뉴얼에서 인용한 것을 들 수 있습니다.「 IGNORE 키워드를 사용하는 경우, INSERT 문을 실행하는 동안 발생하는 에러는 경고로 취급됩니다.예를 들어 IGNORE를 사용하지 않을 경우 테이블 내의 기존 UNIQUIE 인덱스 또는 PRIMAY KEY 값이 중복되는 행은 중복 키 오류를 발생시켜 문이 중단됩니다.)레코드가 아직 존재하지 않으면 레코드가 생성됩니다.
이 두 번째 방법에는 다른 문제가 발생했을 때 쿼리를 중단하지 않는 등 몇 가지 잠재적인 약점이 있습니다(매뉴얼 참조).따라서 IGNORE 키워드를 사용하지 않고 이전에 테스트한 경우 사용해야 합니다.
방법 3: 중복 키 업데이트 시 삽입 사용:
번째 은 '우리'를 사용하는 입니다.
INSERT … ON DUPLICATE KEY UPDATE
구문 및 UPDATE 부분에서는 0+0 계산과 같은 의미 없는(빈) 작업을 수행하지 않습니다(Geofray는 이 작업을 무시하도록 MySQL 최적화 엔진에 id=id 할당을 수행할 것을 권장합니다).이 방법의 장점은 중복된 키이벤트만 무시하며 다른 오류는 계속 중단된다는 것입니다.마지막으로, 이 투고는 Xaprb에서 영감을 얻은 것입니다.또한 유연한 SQL 쿼리 작성에 대한 그의 다른 게시물을 참조할 것을 권장합니다.
솔루션:
INSERT INTO `table` (`value1`, `value2`)
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1)
설명:
가장 안쪽 쿼리
SELECT * FROM `table`
WHERE `value1`='stuff for value1' AND `value2`='stuff for value2' LIMIT 1
로 the the the WHERE NOT EXISTS
를 검출합니다.정지될 수 , 「1」은 「1」의 「1」의 「1」의 「1」입니다.★★★★★★★★★★★★★★★★★★,LIMIT 1
('나름', '나름', '나 '나름'이나 '나름'이나 '나름'이나 '나름'이나 다름없습니다.
중간 쿼리
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
에 삽입할 값을 나타냅니다. DUAL
는 모든 Oracle 데이터베이스에 기본적으로 존재하는 특수한1행, 1열 테이블을 나타냅니다(https://en.wikipedia.org/wiki/DUAL_table) 참조).MySQL-Server 버전 5.7.26에서 다음 항목을 생략할 때 유효한 쿼리를 받았습니다.FROM DUAL
, 이전 .등에서는 ', '(5.5.60)'이 한 것 같습니다FROM
★★★★★★★★★★★★★★★★★★★★★★★.WHERE NOT EXISTS
중간 쿼리는 가장 안쪽 쿼리가 일치하는 데이터를 발견한 경우 빈 결과 세트를 반환합니다.
외부 쿼리
INSERT INTO `table` (`value1`, `value2`)
는 중간 쿼리에 의해 반환된 데이터가 있는 경우 해당 데이터를 삽입합니다.
MySQL에서는 ON DUPLICE KEY UPDATE 또는 INSERT IGNORE가 실행 가능한 솔루션이 될 수 있습니다.
mysql.com에 기반한 ON DUPLICE KEY UPDATE 업데이트의 예:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
mysql.com에 기반한 INSERT IGNORE의 예시
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
또는 다음 중 하나를 선택합니다.
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
또는 다음 중 하나를 선택합니다.
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]
예외가 허용될 경우, 간단한 제약 조건으로도 작업을 수행할 수 있습니다.예:
- 프라이머리 키(대리 키
- 컬럼의 고유 구속조건
- 다열 고유 제약
이것이 믿을 수 없을 정도로 간단해 보인다면 죄송합니다.당신이 우리와 공유하고 있는 링크에 직면했을 때 좋지 않다는 것을 알고 있습니다.;-(
다만, 이 답변은, 고객의 요구를 만족시키는 것 같기 때문에, 이 답변을 드렸습니다(그렇지 않으면, 「좋은 것」(TM)도 갱신할 가능성이 있습니다).
삽입으로 데이터베이스 고유의 제약이 해제될 경우 예외는 드라이버에 의해 릴레이되는 데이터베이스 수준에서 느려집니다.그러면 스크립트가 중단되고 오류가 발생합니다.PHP에서 이 문제를 해결할 수 있어야 합니다.
다음을 시도해 보십시오.
IF (SELECT COUNT(*) FROM beta WHERE name = 'John' > 0)
UPDATE alfa SET c1=(SELECT id FROM beta WHERE name = 'John')
ELSE
BEGIN
INSERT INTO beta (name) VALUES ('John')
INSERT INTO alfa (c1) VALUES (LAST_INSERT_ID())
END
REPLACE INTO `transcripts`
SET `ensembl_transcript_id` = 'ENSORGT00000000001',
`transcript_chrom_start` = 12345,
`transcript_chrom_end` = 12678;
레코드가 존재하면 덮어쓰고 존재하지 않으면 생성됩니다.
지정된 모든 열 값이 테이블에 아직 존재하지 않는 경우에만 행을 삽입하는 PHP 함수가 있습니다.
열 중 하나가 다를 경우 행이 추가됩니다.
테이블이 비어 있으면 행이 추가됩니다.
지정된 모든 열에 지정된 값이 있는 행이 있으면 행이 추가되지 않습니다.
function insert_unique($table, $vars) { if (count($vars)) { $table = mysql_real_escape_string($table); $vars = array_map('mysql_real_escape_string', $vars); $req = "INSERT INTO `$table` (`". join('`, `', array_keys($vars)) ."`) "; $req .= "SELECT '". join("', '", $vars) ."' FROM DUAL "; $req .= "WHERE NOT EXISTS (SELECT 1 FROM `$table` WHERE "; foreach ($vars AS $col => $val) $req .= "`$col`='$val' AND "; $req = substr($req, 0, -5) . ") LIMIT 1"; $res = mysql_query($req) OR die(); return mysql_insert_id(); } return False; }
사용 예:
<?php
insert_unique('mytable', array(
'mycolumn1' => 'myvalue1',
'mycolumn2' => 'myvalue2',
'mycolumn3' => 'myvalue3'
)
);
?>
은 몇 이 있습니다.UNIQUE
할 수 ON DUPLICATE KEY
★★★★★★★★★★★★★★★★★」INSERT IGNORE
, 할 수 없습니다.UNIQUE
에는 길이 제약(1000바이트)이 있습니다.변경할 수 없는 경우가 있습니다.예를 들어 WordPress에서 메타데이터로 작업해야 했습니다.wp_postmeta
를 참조해 주세요.
두 가지 질문으로 해결했습니다.
UPDATE wp_postmeta SET meta_value = ? WHERE meta_key = ? AND post_id = ?;
INSERT INTO wp_postmeta (post_id, meta_key, meta_value) SELECT DISTINCT ?, ?, ? FROM wp_postmeta WHERE NOT EXISTS(SELECT * FROM wp_postmeta WHERE meta_key = ? AND post_id = ?);
1은 일반 1입니다.UPDATE
해당 데이터 세트가 없는 경우 아무런 영향 없이 쿼리합니다.는 '2'입니다.INSERT
은 기호에 따라 .NOT EXISTS
(예:)INSERT
데이터 세트가 존재하지 않는 경우에만 실행됩니다.
주의할 점은 INSERT IGNORE는 일반 INSERT와 마찬가지로 스테이트먼트의 성공 여부에 관계없이 프라이머리 키가 증가한다는 것입니다.
이로 인해 프로그래머가 정신적으로 불안정해질 수 있는 주요 키의 공백이 발생할 수 있습니다.또는 애플리케이션이 제대로 설계되지 않고 완벽한 증분 기본 키에 의존하는 경우 골칫거리가 될 수 있습니다.
innodb_autoinc_lock_mode = 0
(서버 설정 및 약간의 퍼포먼스 히트 포함), 또는 SELECT를 사용하여 쿼리가 실패하지 않는지 확인합니다(퍼포먼스 히트 및 추가 코드 포함).
알 수 없는 기본 키 없이 업데이트 또는 삽입
키나 키가 , 에서는 '키를 '키'로 합니다.INSERT INTO ... ON DUPLICATE KEY UPDATE ...
★★★★★★★★★★★★★★★★★」REPLACE INTO ...
는 정상적으로 동작합니다(존재하는 경우는 삭제로 치환하고 나서 삽입하는 것에 주의해 주세요).따라서 기존 값은 부분적으로 갱신되지 않습니다.
, 지지 for for for for some_column_id
★★★★★★★★★★★★★★★★★」some_type
이들 조합은 고유하다고 알려져 있습니다. 업데이트 하고 some_value
있는 경우 삽입하거나 없는 경우 삽입하십시오.트랜잭션 사용을 피하기 위해 한 번의 쿼리로 작업을 수행할 수 있습니다.을 사용하다
INSERT INTO my_table (id, some_column_id, some_type, some_value)
SELECT t.id, t.some_column_id, t.some_type, t.some_value
FROM (
SELECT id, some_column_id, some_type, some_value
FROM my_table
WHERE some_column_id = ? AND some_type = ?
UNION ALL
SELECT s.id, s.some_column_id, s.some_type, s.some_value
FROM (SELECT NULL AS id, ? AS some_column_id, ? AS some_type, ? AS some_value) AS s
) AS t
LIMIT 1
ON DUPLICATE KEY UPDATE
some_value = ?
기본적으로 쿼리는 다음과 같이 실행됩니다(생각보다 덜 복잡함).
- 합니다.
WHERE
절이 일치합니다. - 행이 될 이 있는 표)
s
컬럼 값이 명시적으로 지정됩니다(s.id은 NULL이므로 새로운 자동 인식 식별자가 생성됩니다). - 이 나올 .
s
) 폐기됩니다(「LIMIT 1」).t
) 、 、 、 、 、 、 、 、 、 、 an an an an an an an an an an an an an an an an an an an an an an 。ON DUPLICATE KEY
UPDATE
some_value
★★★★★★ 。 - 수 없는 경우 새표).
s
를 참조해 주세요.
내의 증가치가 .「 」 。id
기 if. 만약 당신이 이것이 없다면, 첫눈에 필요없을 때에도 그것을 추가하세요.이 "꼼수"를 위해 반드시 필요합니다.
INSERT INTO table_name (columns) VALUES (values) ON CONFLICT (id) DO NOTHING;
언급URL : https://stackoverflow.com/questions/1361340/how-can-i-do-insert-if-not-exists-in-mysql
'programing' 카테고리의 다른 글
Javascript에 var_dump(PHP)와 동등한 것이 있습니까? (0) | 2022.11.06 |
---|---|
SQL에서 열의 최대값이 있는 행만 선택 (0) | 2022.11.06 |
@여러 메서드 인수의 캐시 가능한 키 (0) | 2022.11.06 |
메서드 선언은 PHP의 상위 메서드와 호환되어야 합니다. (0) | 2022.11.06 |
JavaScript에서 변수가 숫자인지 문자열인지 확인합니다. (0) | 2022.10.27 |