mysql - 适用于主要数据库的更新语法

标签 mysql sql sql-server oracle ansi

我想根据另一个表 (source) 中存在的值更新一个表 (target)。但我正在寻找一种适用于 4 个主要数据库的语法 - Oracle、MS SQL Server、PostgreSQL、MySQL。

到目前为止,我还没有找到这样一个统一的语法。我错过了这样的语法还是真的没有这样的语法?

甲骨文

UPDATE target t
SET (t.col1, t.col2) = (SELECT s.col1, s.col2 
                       FROM source s 
                       WHERE s.key = t.key)

MS SQL Server/PostgreSQL

UPDATE target t
SET t.col1 = s.col1, t.col2 = s.col2
FROM source s
WHERE t.key=s.key

MySQL

UPDATE target, source 
SET t.col1=s.col1, t.col2=s.col2
WHERE s.key=t.key

最佳答案

这是低效的,但 ANSI SQL 标准的方法是:

UPDATE target
SET col1 = (SELECT s.col1
           FROM source s 
           WHERE s.key = target.key),
    col2 = (SELECT s.col2 
           FROM source s 
           WHERE s.key = target.key);

这并不意味着它适用于每个 RDBMS(例如,我认为它不适用于 Access),但它确实适用于您列出的 4 个 RDBMS。

我个人会在一周的每一天都重视性能而不是可移植性,所以我不会使用这种语法。我倾向于使用存储过程,每个 RDBMS 都有一个通用名称,但语法不同。

更新

实际上,ANSI SQL 标准也允许使用行值构造函数为 Oracle 展示的方法:

UPDATE target
SET (t.col1, t.col2) = (SELECT s.col1, s.col2 
                       FROM source s 
                       WHERE s.key = t.key);

不幸的是,如上所述,仅仅因为它符合 ANSI 标准并不意味着它可以跨平台工作。

关于mysql - 适用于主要数据库的更新语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32437367/

相关文章:

MYSQL - 触发器 : IF Date is null, 将日期设置为 CURDATE INTERVAL 1 天

mysql - 对于 MySQL,是否有工具可以从一个表中转储一组行,并从所有相关表中转储所有相关(通过外键)行?

mysql - SQL 查询问题 : Cannot get desired output

mysql - 如何在 select 语句中生成条件数字列

c# - EDMX 对象引用未设置为对象的实例

php - mysql 事件调度是合适的(或最佳的)解决方案吗?

mysql - 如何创建一个子查询而不是联合查询

mysql Rand() 函数导致意外的多行结果

mysql - MySQL 和 PostgreSQL 通用的 MONTH() 和 YEAR() 函数的任何替代方法

sql-server - 将 xml 列值包装到外部以进行 xml 路径查询