2014-12-23 5 views
0

두 번째 반복에서 일관되게 실패하는 간단한 (단일 테이블) 업데이트 쿼리 집합을 처리하는 프레임 워크가 있습니다. 내 프레임 워크 내에서 키 - 값 (col-data) 쌍의 연관 배열을 기반으로 준비된 UPDATE 쿼리를 작성합니다. 다음과 같이여러 개의 준비된 쿼리 업데이트를 수행하는 PHP 코드가 두 번째 반복에서 중복 키 오류로 인해 실패합니다.

I가 발생하고 문제는 :

foreach ($data as $row) call update($row); // pseudo code 

프레임 워크는 각 행의 (준비) 업데이트 쿼리를 작성하고 작업에 대한 상태/상태를 반환합니다.

첫 번째 쿼리가 항상 실행하고 성공적으로 업데이트하지만, 메소드의 두 번째 쿼리가 지속적으로 오류가 반환

처음

중복 항목 {값} {키} 키를, 나에 대한 복합 PKEY했다 cols B, C, D가 기본 키인 테이블. 테스트를 위해 복합 키를 제거하려고했지만 "고유"(기본이 아닌)로 표시된 auto-inc 필드에 오류가 발생합니다.

디버거에서 추적을 실행하면 어디에서 prepare()가 성공적인지 알 수 있지만 두 번째 쿼리는 위의 오류를 생성하는 execute()에서 실패합니다.

또한, 추적하는 동안, 나는 문 발생했음을 보장 :

$ dblink-> next_result를();

두 번째 명령문이 작성되기 전에.

UPDATE /* /home/sn-m-beds/classes/MBEDS_mySQL.class.inc:(1982) */ config_cfg SET id_cfg = ?, ent_cfg = ?, hash_cfg = ?, key_cfg = ?, value_cfg = ?, modified_cfg = NOW() WHERE idHash_cfg = ? 

및 $ 결과의 내용 ($에서 그 결과를 행> 실행()) 위치 :

MySQL의 로그의 제조 (제 문 동일 2 번째의 고장의 문) 문을 보여

affected_rows = -1 
insert_id = 0 
num_rows = 0 
param_count = 6 
field_count = 0 
errno = 1062 
error = "Duplicate entry '31' for key 'id_cfg'" 
error_list = {array} (as above) 
sqlstate = "23000" 
id = 9 

분명히 composite-primary-key를 삭제하는 것은 mysql에 관한 한 영향을 미치지 않습니다.

각 반복마다 DB 링크 리소스를 생성 (분리)했지만 동일한 결과가 제공되었습니다.

내가 무엇을 볼 수 있는지 잘 모르겠지만 ... 어떤 제안이나 아이디어라도 크게 감사 할 것입니다.

감사합니다.

--mike

업데이트 : 12/23/14 : 나는 바인드에 대한 모든 코드를 보여 주저 해요

가 준비/- 거기 많이 생성에 관여하는 코드의 및 쿼리를 준비합니다. 애플리케이션의 트랙 레코드에서이 메서드를 사용하여 생성 된 쿼리는 항상 성공적이라는 것을 알았습니다. 연속 쿼리를 제출하기 전까지는 프레임 워크가 1 년 넘게 프로덕션 환경에있었습니다.

나는 쿼리가 실행되는 것을 믿지 않는다 - where-clause discriminant 한정자가 고유 키 (idHash_cfg)에 대해 exec'ing하고있다 -이 코어 멤버 함수를 호출하기 전에 데이터 튜플 idHash 키가 존재하면, no-idHash 값이 삽입 명령을 빌드하는 메소드에 대한 호출을 생성하는 db tuple을 update()하는 메소드가 호출됩니다. 두 경우 모두 $ data [] 튜플은 args 중 하나로서 메서드에 전달됩니다.

프레임 워크 내에서 각 클래스 인스턴스화에는 $ data라는 보호 멤버가 있으며이 멤버는 튜플 배열이 될 수 있습니다. 쿼리 작성기는 $ 데이터 연관 배열의 각 행에 대한 쿼리를 작성, 준비 및 실행합니다.

첫 번째 쿼리 exec가 성공적으로 수행됩니다. 모든 후속 쿼리가 구문 상 올바른 (동일한 코드)로 빌드되고 있지만 앞에서 설명한 오류로 실패합니다.

이 문제는 mysqli의 db-link 리소스 중 하나라고 생각합니다. MySQL 내부, 참조 또는 리소스 또는 호출하려는 항목이 후속 쿼리의 성공적인 실행을 방해합니다. - 엔터, 해시 키 컬럼의 조합

*************************** 1. row *************************** 
    Table: config_cfg 
Create Table: CREATE TABLE `config_cfg` (
    `id_cfg` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'pkey', 
    `ent_cfg` char(3) NOT NULL COMMENT 'TLA for entity type', 
    `hash_cfg` char(32) NOT NULL COMMENT 'hash key for the entity', 
    `key_cfg` varchar(32) NOT NULL COMMENT 'configuration key value name', 
    `value_cfg` varchar(32) NOT NULL COMMENT 'value assigned to the key', 
    `created_cfg` datetime DEFAULT NULL, 
    `createdBy_cfg` char(32) DEFAULT NULL, 
    `accessed_cfg` datetime DEFAULT NULL, 
    `modified_cfg` datetime DEFAULT NULL, 
    `status_cfg` varchar(50) DEFAULT 'ACTIVE', 
    `sessionIP_cfg` char(15) DEFAULT NULL, 
    `idHash_cfg` char(32) DEFAULT NULL, 
    UNIQUE KEY `id_cfg` (`id_cfg`), 
    UNIQUE KEY `idHash_cfg` (`idHash_cfg`), 
    KEY `status_cfg` (`status_cfg`), 
    KEY `ent_cfg` (`ent_cfg`), 
    KEY `hash_cfg` (`hash_cfg`), 
    KEY `key_cfg` (`key_cfg`), 
    CONSTRAINT `config_cfg_ibfk_1` FOREIGN KEY (`status_cfg`) REFERENCES `status_sts` (`name_sts`) 
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=latin1 COMMENT='container for entity configuration settings/values' 
1 row in set (0.00 sec) 

그래서, 처음에 내가 기본 키로 복합 인덱스를 가지고 :

여기에 테이블 SQL을 작성합니다. 진단에 도움이되는 복합 키 복잡성을 제거하기 위해 색인을 삭제했습니다. 덤프에서 볼 수 있듯이, 지금은 일반 키를 다루고 있습니다.

쿼리가 실행되는 일부 코드 조각

:

if ($result = $dbLink->prepare($this->strQuery)) { 
if (call_user_func_array(array($result, 'bind_param'), $bp->refValues($bp->get()))) { 
    if ($result->execute()) { 
     // [ snip... ] 
    } else { // where error reports are coming from 
     snsError::set(ERROR_FATAL, 'query execution failure'); 
     snsError::set(ERROR_FATAL, $this->strQuery); 
     snsError::set(ERROR_FATAL, $result->error); 
     $success = false; 
     $this->state = DATA_STATUS_MYSQL_ERROR; 
    } 
+1

이것은 인덱스를 수정해야하는 것보다 훨씬 무해한 것으로 보입니다. 루프에 준비, 바인딩 및 실행하는 데 사용 된 코드를 게시하십시오. 거기에는 사소한 논리 문제가있을 수 있으므로 게시하십시오. –

+0

또한 SHOW CREATE TABLE config_cfg에서 출력을 게시하여 현재 존재하는 모든 인덱스의 구조를 볼 수 있습니다. –

+0

복합 기본 키가 처음에는 좋았지 만 실행 취소 복잡성이 발생합니다. 'update table set value ='foo '여기서 id = 1' 대'update table set value = 'foo'where col_a = 1 and col_b = 2' –

답변

1

id_cfg는 NOT NULL AUTOINCREMENT입니다. INSERT 문에서 설정하지 않아야합니다. 그것을 밖으로두고 mysql이 당신을 위해 그것을 채우도록하십시오! 명령문과 자리 표시 자에 바인딩하는 값 배열에서 제거하십시오.

UPDATE /* /home/sn-m-beds/classes/MBEDS_mySQL.class.inc:(1982) */ config_cfg 
SET id_cfg = ?, ent_cfg = ?, hash_cfg = ?, key_cfg = ?, value_cfg = ?, modified_cfg = NOW() 
WHERE idHash_cfg = ? 
-1

TL; DR : 문제

인덱싱 문제 무관 ... 복합 키 ID 등

대신 입력 튜플을 분석 하였다 .. 코드이고, I는 페치 하였다 pkey 정보를 클래스 멤버에서 가져오고, 인덱스가 전달되지 않은 경우에는 0 번째 튜플을 기본값으로 사용합니다. 영향을받은 코드는 첫 번째 gen이었고 n 튜플을 고려하지 않았습니다. 데이터 회원.

일단 n 튜플을 처리하기 위해 핵심 코드를 리팩토링 했더니 모두 잘 돌아 왔습니다.

모든 의견과 제안을 보내 주셔서 감사합니다. 저에게 맞는 장소를 찾기 시작했습니다.

관련 문제