一尘不染

准备具有DEFAULT值的MySQL INSERT / UPDATE语句

mysql

引用MySQL INSERT手册-UPDATE也一样:

使用关键字DEFAULT可以将列明确设置为其默认值。这使编写INSERT语句(为少数几个列分配值)更加容易,因为它使您避免编写不完整的VALUES列表,该列表不包含表中每个列的值。否则,您将不得不写出与VALUES列表中的每个值相对应的列名列表。

简而言之,如果我写

INSERT INTO table1 (column1,column2) values ('value1',DEFAULT);

插入新的一列,并将column2设置为其默认值(无论它是多少)。

但是,如果我准备并执行PHP语句:

$statement = $pdoObject->
    prepare("INSERT INTO table1 (column1,column2) values (?,?)");
$statement->execute(array('value1','DEFAULT'));

如果该列能够存储文本值,则新行将包含“ DEFAULT”作为其文本值。

现在,我已经为PDO编写了一个抽象层(我需要它),为了解决这个问题,我正在考虑引入一个

const DEFAULT_VALUE = "randomstring";

所以我可以执行这样的语句:

$statement->execute(array('value1',mysql::DEFAULT_VALUE));

然后在执行绑定的方法中,我将检查发送给绑定的值,如果某些值等于self::DEFAULT_VALUE,则相应地执行操作。

我敢肯定,有更好的方法可以做到这一点。有人遇到过类似情况吗?


阅读 536

收藏
2020-05-17

共1个答案

一尘不染

我知道的唯一“解决方法”是使用Coalesce()Default(fieldname)

例如

$pdo = new PDO("mysql:host=localhost;dbname=test", 'localonly', 'localonly'); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$pdo->exec("
  CREATE TEMPORARY TABLE foo (
    id int auto_increment,
    x int NOT NULL DEFAULT 99,
    y DATETIME NOT NULL DEFAULT '2010-03-17 01:00:00',
    z varchar(64) NOT NULL DEFAULT 'abc',
    primary key(id)
  )
");


$stmt = $pdo->prepare('
  INSERT INTO
    foo
    (x,y,z)
  VALUES
    (
      Coalesce(:x, Default(x)),
      Coalesce(:y, Default(y)),
      Coalesce(:z, Default(z))
    )
');
$stmt->bindParam(':x', $x);
$stmt->bindParam(':y', $y);
$stmt->bindParam(':z', $z);


$testdata = array(
  array(null, null, null),
  array(1, null, 'lalala'),
  array(null, '2009-12-24 18:00:00', null)
);
foreach($testdata as $row) {
  list($x,$y,$z) = $row;
  $stmt->execute();
}
unset($stmt);
foreach( $pdo->query('SELECT id,x,y,z FROM foo', PDO::FETCH_NUM) as $row) {
  echo join(', ', $row), "\n";
}

版画

1, 99, 2010-03-17 01:00:00, abc
2, 1, 2010-03-17 01:00:00, lalala
3, 99, 2009-12-24 18:00:00, abc
2020-05-17