我正在使用CakePHP 3.x
There is a way to execute transactions in CakePHP 3.x
但是,我的一些执行语句需要前面插入语句的id。
如何在选择CakePHP 3.x并允许PostgreSQL或MySQL作为我的数据库时在事务中执行该操作?
我期望的查询是这样的:
INSERT INTO dynamic_views (`title`, `created`) values ('view 37', NOW());
-- take the id of the above insert query and assuming the view id is 37
INSERT INTO users_access_dynamic_views(user_id, view_id) values (44, 37);
我想使用CakePHP3.x使用事务执行上述操作。
同时,我想问一下,对于上述情况使用交易是否被认为是个坏主意?
答案 0 :(得分:5)
执行插入查询后,您可以使用正确的参数调用lastInsertId()
以获取正确的值:
$connection->transactional(function ($connection) {
$statement = $connection->newQuery
->insert($fields)
->into($table)
->values($values)
->execute();
$insertId = $statement->lastInsertId($table, 'id'); // id is primary key
});
答案 1 :(得分:1)
在MySQL中获取最后插入的id的函数称为last_insert_id(),而在PostgreSQL中它是lastval()。因此,要么必须在两者之间创建一些映射,要么必须检查CakePHP中使用的驱动程序,然后调用特定的函数。
例如,您可以在PostgreSQL中创建以下函数。
CREATE FUNCTION last_insert_id() RETURNS BIGINT AS $$
SELECT lastval();
$$ LANGUAGE sql VOLATILE;
然后你可以在第二个查询中调用它,它将在MySQL和PostgreSQL中都有效。
INSERT INTO users_access_dynamic_views
(user_id, view_id)
VALUES
(44, LAST_INSERT_ID());
还要注意PostgreSQL使用序列来生成ID,因此当涉及触发器(在自己的某处插入数据)时,仅依靠lastval
可能会产生意外结果。因此,最好通过currval
明确指定所涉及的序列。
CURRVAL(PG_GET_SERIAL_SEQUENCE('dynamic_views', 'view_id'))