programing

다중 삽입 쿼리를 준비할 때 오류가 발생했습니다.

javamemo 2023. 9. 27. 16:47
반응형

다중 삽입 쿼리를 준비할 때 오류가 발생했습니다.

// BUILD VALUES
$count = count($matches);
for($i = 0; $i < $count; ++$i) {
    $values[] = '(?)';
}
// INSERT INTO DATABASE
$q = $this->dbc->prepare("INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash = hash");
$q->execute($matches);

위의 코드는 다음 오류와 함께 실패합니다.

SQLSTATE[HY093]:매개 변수 번호가 잘못되었습니다. 매개 변수가 정의되지 않았습니다.

비록 언제count($matches) == count($values)실행이 시작되기 바로 전에?

이게 무슨 일입니까?

당신이 받는 이 오류는 에 있는 요소의 수가 많기 때문입니다.$values&$matches일치하지 않습니다.

한다면$values&$matches동일한 수의 요소를 포함하지 않으면 X 매개 변수가 예상되지만 Y 데이터를 수신하는 쿼리로 인해 삽입이 실패합니다.$matches. 당신 같은 경우엔$values이미 몇 가지 값이 포함되어 있을 수 있습니다. 이것이 카운트 불일치의 원인입니다.이를 방지하려면 루프 전에 항상 배열을 초기화해야 합니다.

칼럼 해시에도 고유한 인덱스가 있는지 확인해야 할 것 같습니다.

$matches = array('1');
$count = count($matches);
$values = [];
for($i = 0; $i < $count; ++$i) {
    $values[] = '(?)';
}

// INSERT INTO DATABASE
$sql = "INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash=values(hash)";
$stmt = $dbh->prepare($sql);
$data = $stmt->execute($matches);

SQLSTATE[HY093]:매개 변수 번호가 잘못되었습니다. 매개 변수가 정의되지 않았습니다.

안타깝게도 이 오류는 동일한 문제와 관련된 다양한 문제인 바인딩 오류에 대해 설명할 수 없습니다.또한 오류가 어디에 있는지 명시하지 않으므로 사용자의 문제는 반드시 실행에 있는 것이 아니라 이미 '준비'된 sql 문입니다.

발생 가능한 오류와 해결책은 다음과 같습니다.

  1. 매개 변수가 일치하지 않습니다. 필드 수가 바인딩된 매개 변수와 일치하지 않습니다.어레이의 어레이를 주의해야 합니다.다시 확인하려면 var_dump($var)를 사용합니다."print_r"은 배열의 인덱스가 다른 배열인지(열에 하나의 값이 있는 경우)를 반드시 표시하지는 않지만 var_dump는 표시합니다.

  2. 동일한 바인딩 값(예: ":hash" 및 ":hash")을 사용하여 바인딩을 시도했습니다.모든 인덱스는 논리적으로 동일한 값이라도 두 개의 다른 부분에 대해 동일한 것을 사용하는 것이 타당하더라도 고유해야 합니다.(상수와 비슷하지만 자리지킴이에 가깝습니다)

  3. 문에서 두 개 이상의 값을 바인딩하는 경우("INSERT"의 경우가 대부분), Param을 바인딩한 다음 Value를 매개 변수에 바인딩해야 합니다.여기서는 매개변수를 필드에 바인딩한 다음 값을 매개변수에 바인딩합니다.

     // Code snippet
     $column_names = array();
     $stmt->bindParam(':'.$i, $column_names[$i], $param_type);
     $stmt->bindValue(':'.$i, $values[$i], $param_type);
     $i++;
     //.....
    
  4. 문자열이 아닌 식별자를 나타내는 리터럴을 구분하기 위해 백틱을 사용할 때 일관성이 없을 경우.( ''를 사용) 그러나 일단 사용하면 해당 쿼리에 대해 일관성을 유지해야 합니다. 즉, 한 식별자에 대해 백틱을 사용할 수 없고 다른 식별자에 사용할 수 없으므로 사용할 경우 모두 백틱을 사용해야 합니다.(예: SELECT)id.my_table하지 말 것)

  5. ''' 작은 따옴표의 값은 항상 문자열 리터럴로 처리되며 바인딩할 열/테이블 이름 또는 자리 표시자로 읽을 수 없습니다.

바인딩 시 파라미터 이름을 잘못 사용한 후 동일한 오류가 발생하였습니다.

알림: tokenHash in theVALUES쿼리의 절이지만 바인딩 시 : token_hash.

이런저런 문제를 해결하면 오류가 해결됩니다.

// Prepare DB connection
$sql = 'INSERT INTO rememberedlogins (token_hash,user_id,expires_at)
        VALUES (:tokenHash,:user_id,:expires_at)';
$db = static::getDB();
$stmt = $db->prepare($sql);

// Bind values
$stmt->bindValue(':token_hash',$hashed_token,PDO::PARAM_STR);

PHP의 컬럼명과 데이터베이스 컬럼명이 일치하지 않는 경우 동일한 오류가 나타날 것입니다. 그것도 다시 한번 확인해보세요.이것이 제가 잘못한 것입니다.

답변이 유용했던 것은 이해하지만, 어떤 이유에서인지 저에게는 통하지 않지만, 아래 코드로 상황을 옮겼고 완벽합니다.

    <?php

$codigoarticulo = $_POST['codigoarticulo'];
$nombrearticulo = $_POST['nombrearticulo'];
$seccion        = $_POST['seccion'];
$precio         = $_POST['precio'];
$fecha          = $_POST['fecha'];
$importado      = $_POST['importado'];
$paisdeorigen   = $_POST['paisdeorigen'];
try {

  $server = 'mysql: host=localhost; dbname=usuarios';
  $user   = 'root';
  $pass   = '';
  $base   = new PDO($server, $user, $pass);

  $base->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $base->query("SET character_set_results = 'utf8',
                     character_set_client = 'utf8',
                     character_set_connection = 'utf8',
                     character_set_database = 'utf8',
                     character_set_server = 'utf8'");

  $base->exec("SET character_set_results = 'utf8',
                     character_set_client = 'utf8',
                     character_set_connection = 'utf8',
                     character_set_database = 'utf8',
                     character_set_server = 'utf8'");

  $sql = "
  INSERT INTO productos
  (CÓDIGOARTÍCULO, NOMBREARTÍCULO, SECCIÓN, PRECIO, FECHA, IMPORTADO, PAÍSDEORIGEN)
  VALUES
  (:c_art, :n_art, :sec, :pre, :fecha_art, :import, :p_orig)";
// SE ejecuta la consulta ben prepare
  $result = $base->prepare($sql);
//  se pasan por parametros aqui
  $result->bindParam(':c_art', $codigoarticulo);
  $result->bindParam(':n_art', $nombrearticulo);
  $result->bindParam(':sec', $seccion);
  $result->bindParam(':pre', $precio);
  $result->bindParam(':fecha_art', $fecha);
  $result->bindParam(':import', $importado);
  $result->bindParam(':p_orig', $paisdeorigen);
  $result->execute();
  echo 'Articulo agregado';
} catch (Exception $e) {

  echo 'Error';
  echo $e->getMessage();
} finally {

}

?>

언급URL : https://stackoverflow.com/questions/10966251/error-when-preparing-a-multiple-insert-query

반응형