Insert or update with a single operation using PDOdb's portable UPSERT.
Insert or update if duplicate key exists:
use tommyknocker\pdodb\helpers\Db;
$db->find()->table('users')
->onDuplicate([
'last_login' => Db::now(),
'login_count' => Db::inc()
])
->insert([
'email' => 'alice@example.com',
'name' => 'Alice',
'last_login' => Db::now()
]);$db->find()->table('users')
->onDuplicate([
'name' => Db::raw('VALUES(name)'),
'age' => Db::raw('VALUES(age)'),
'updated_at' => Db::now()
])
->insert([
'email' => 'alice@example.com', // Unique key
'name' => 'Alice',
'age' => 30
]);INSERT INTO users (email, name, age)
VALUES (:email, :name, :age)
ON DUPLICATE KEY UPDATE
name = VALUES(name),
age = VALUES(age),
updated_at = NOW()INSERT INTO users (email, name, age)
VALUES (:email, :name, :age)
ON CONFLICT (email) DO UPDATE SET
name = EXCLUDED.name,
age = EXCLUDED.age,
updated_at = CURRENT_TIMESTAMPINSERT INTO users (email, name, age)
VALUES (:email, :name, :age)
ON CONFLICT (email) DO UPDATE SET
name = EXCLUDED.name,
age = EXCLUDED.age,
updated_at = CURRENT_TIMESTAMP// Insert or increment counter
$db->find()->table('views')
->onDuplicate([
'count' => Db::raw('count + 1'),
'last_viewed' => Db::now()
])
->insert([
'page_id' => $pageId,
'count' => 1,
'last_viewed' => Db::now()
]);// Track user activity
$db->find()->table('user_activity')
->onDuplicate([
'last_active' => Db::now(),
'visit_count' => Db::inc()
])
->insert([
'user_id' => $userId,
'last_active' => Db::now(),
'visit_count' => 1
]);// Update existing or create new
$db->find()->table('user_settings')
->onDuplicate([
'theme' => Db::raw('VALUES(theme)'),
'updated_at' => Db::now()
])
->insert([
'user_id' => $userId,
'theme' => 'dark',
'updated_at' => Db::now()
]);$db->find()->table('user_preferences')
->onDuplicate([
'value' => Db::raw('VALUES(value)'),
'updated_at' => Db::now()
])
->insert([
'user_id' => $userId,
'key' => 'theme',
'value' => 'dark',
'updated_at' => Db::now()
]);
// Conflicts on (user_id, key)$db->find()->table('users')->replace([
'id' => 1,
'name' => 'Alice Updated',
'email' => 'alice@example.com'
]);$users = [
['id' => 1, 'name' => 'Alice', 'email' => 'alice@example.com'],
['id' => 2, 'name' => 'Bob', 'email' => 'bob@example.com']
];
$db->find()->table('users')->replaceMulti($users);REPLACE INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com');INSERT INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')
ON CONFLICT (id) DO UPDATE SET
name = EXCLUDED.name,
email = EXCLUDED.email// Safe to call multiple times
function trackUserLogin($userId) {
$db->find()->table('user_activity')
->onDuplicate(['last_login' => Db::now(), 'count' => Db::inc()])
->insert(['user_id' => $userId, 'last_login' => Db::now(), 'count' => 1]);
}// ✅ Good: Include all data
$db->find()->table('users')
->onDuplicate(['updated_at' => Db::now()])
->insert([
'email' => 'alice@example.com',
'name' => 'Alice',
'age' => 30
]);
// ❌ Bad: Missing data on conflict
$db->find()->table('users')
->onDuplicate(['updated_at' => Db::now()])
->insert(['email' => 'alice@example.com']); // Only email set- Data Manipulation - INSERT, UPDATE, DELETE
- Batch Operations - Bulk inserts
- Transactions - Transaction management