【发布时间】:2020-01-14 09:31:45
【问题描述】:
我有一个 PHP 7.3 项目,它通过 PDO 连接到 MySQL 数据库或 MSSQL 数据库,具体取决于在 Linux 或 Windows 上运行。
如果唯一值尚未在该表中,我想将新值插入表中。如果它已经在表中,我想更新非唯一值。
我也搜索了很多文档和 SO 帖子,但我找不到一种语法,它在一个查询中针对两种数据库类型。
SQL Server 查询:
IF (EXISTS (SELECT * FROM failed_logins_ip_address WHERE ip_address = 'xxx'))
BEGIN
UPDATE failed_logins_ip_address
SET attempts_count = attempts_count + 1, attempt_datetime = CURRENT_TIMESTAMP
WHERE ip_address = 'xxx'
END
ELSE
BEGIN
INSERT INTO failed_logins_ip_address (ip_address, attempts_count, attempt_datetime)
VALUES ('xxx', 1, CURRENT_TIMESTAMP)
END
MySQL 查询:
INSERT INTO failed_logins_ip_address (ip_address, attempts_count, attempt_datetime)
VALUES ('xxx', 1, CURRENT_TIMESTAMP)
ON DUPLICATE KEY
UPDATE attempts_count = attempts_count + 1, attempt_datetime = CURRENT_TIMESTAMP
'ip_addess' 列是唯一的,MSSQL 和 MySQL 的表结构相同。
是否有可以在两种数据库类型中执行 IF INSERT ELSE UPDATE 的语法?
是的,我做(PDO)参数绑定,xxx只是为了缩短代码sn-p。
是的,如果我在两个查询(首先选择,然后插入或更新)中执行相同的语法,我可以使用相同的语法,但我想避免(希望)不必要的查询。
不,我不想插入每次登录尝试,因此我不再需要更新,因为我不需要这些数据。
如果 REPLACE 方法可行:这不会更新,它会删除和插入,这也是我不想要的。
我当前的解决方案:我在 PHP 中检查当前数据库类型并切换/大小写查询字符串。它很干净,但一根绳子更不臭;-)
更新:
我改变了 MSSQL 查询:从 IF NOT EXISTS 到 IF EXISTS 以提高效率。 UPDATE 会比 INSERT 更频繁地发生,因此在大多数情况下,只会执行第一个(子)查询。
【问题讨论】:
-
您搜索了很多,但没有找到任何关于
MERGE的信息? -
@Sami
MERGE在 MySQL 中不存在。我认为 OP 试图在 MySQL 和 SQL Server 之间找到一个共同的功能。 -
在 MySQL 和 SQL Server AFAIK 中都没有通用的方法。
-
与其寻找通用语法,不如在两者上创建同名的存储过程?
-
@jasie 您可以使用 MySQL / SQL 服务器的相应语法创建存储过程(例程),并立即将其定义到服务器中。您可以确保两个存储过程具有相同的名称。现在对SQL Server不太熟悉,不过好像支持
CALL ..语句,MySQL也支持。所以你可以简单地用通用名称调用存储过程
标签: php mysql sql sql-server insert-update