何时在 PHP 中使用 OCI_B_INT?

When to use OCI_B_INT in PHP?

我有一个具有以下结构的 Oracle table:

column             type           key
---------------------------------------------
id                 integer        primary key
user_id            integer        foreign key
colony_id          number(14)     foreign key
last_upd_username  varchar2(50)
last_upd_date      date

我没有创建 table 但我认为 colony_id 也应该是 integer - 而不是 number (现在太晚了无论如何都要改变它).

我有一个插入多行的查询 table:

$colonies = array_map("intval", $post['colonies']);

# Assign colonies to $user_id
$sql = "INSERT INTO user_colonies (
    id,
    user_id,
    colony_id,
    last_upd_username,
    last_upd_date
  ) VALUES (
    user_colonies_seq.NEXTVAL,
    :user_id,
    :colony_id,
    :username,
    sysdate
  )";

$stmt = oci_parse($conn, $sql);
oci_bind_by_name($stmt, ":user_id", $user_id);
oci_bind_by_name($stmt, ":colony_id", $colony);
oci_bind_by_name($stmt, ":username", $username);

foreach($colonies as $colony) {
  $r = oci_execute($stmt, OCI_DEFAULT);
  if(!$r) {
    $e = oci_error($stmt);
    $result['err'][] = $e['message'];
  }
}

$result['msg'] = 'success';

oci_commit($conn);
oci_free_statement($stmt);

echo json_encode($result);

这种工作因为查询运行良好 ($e['message']) 总是 null。但是,当我查看插入的行时,colony_id 没有任何意义,它们只是一堆从 1 到 9 的随机整数,而我期待的是实际 ID(应该是数千个)。

我能够通过更改

使其工作
oci_bind_by_name($stmt, ":colony_id", $colony);

进入

oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);

通过使用 OCI_B_INT,使用了正确的 ID,一切正常。我不明白何时以及如何使用该标志,因为绑定 $user_id":user_id" 在没有标志的情况下工作正常。我能看到的唯一区别是数据类型(integer vs number(14))。

这确实不是 OCI_B_INT 标志的问题。真正的罪魁祸首是 maxlength 参数。

You must specify maxlength when using an OUT bind so that PHP allocates enough memory to hold the returned value.

For IN binds it is recommended to set the maxlength length if the statement is re-executed multiple times with different values for the PHP variable. Otherwise Oracle may truncate data to the length of the initial PHP variable value. If you don't know what the maximum length will be, then re-call oci_bind_by_name() with the current data size prior to each oci_execute() call. Binding an unnecessarily large length will have an impact on process memory in the database.

foreach($colonies as $colony) {
  oci_bind_by_name($stmt, ":colony_id", $colony, -1, OCI_B_INT);
  $r = oci_execute($stmt, OCI_DEFAULT);
}