mysql - 在 PostgreSQL 中替代 MySQL 的变量?

标签 mysql postgresql variables plpgsql temporary

我们经常使用快速的一次性 SQL 文件在现有数据库中插入或更新数据。 SQL 通常由开发人员编写,在开发系统上进行测试,然后使用 psql -U dbuser dbname < file.sql 导入到生产数据库中.

一个(简单的)示例可能如下所示:

INSERT INTO employees (
    company_id,
    name,
    position,
    created_by,
    last_modified_by
) VALUES
(
    (SELECT id FROM companies WHERE name = 'Acme Fellowship'),
    'Frodo Baggins',
    'Ring bearer',
    (SELECT id FROM users WHERE login = 'admin'),
    (SELECT id FROM users WHERE login = 'admin')
),
(
    (SELECT id FROM companies WHERE name = 'Acme Fellowship'),
    'Samwise Gamgee',
    'Rope bearer',
    (SELECT id FROM users WHERE login = 'admin'),
    (SELECT id FROM users WHERE login = 'admin')
),
(
    (SELECT id FROM companies WHERE name = 'Acme Fellowship'),
    'Peregrin Took',
    'Ent rider',
    (SELECT id FROM users WHERE login = 'admin'),
    (SELECT id FROM users WHERE login = 'admin')
);

虽然这可行,但子查询中有很多重复代码。存储 companies.id 的相关值会很好(效率更高且更不容易出错)和 users.id在临时变量中。在这个解释的例子中,性能差异可能很小,但在实践中我们确实有更复杂的查询和更新,并且通常有超过三个更新/插入的记录。

为 MySQL 编写的相同示例如下所示:

SELECT @company_id := id FROM companies WHERE name = 'Acme Fellowship';
SELECT @admin_id := id FROM users WHERE login = 'admin';
INSERT INTO employees (
    company_id,
    name,
    position,
    created_by,
    last_modified_by
) VALUES
(@company_id, 'Frodo Baggins',  'Ring bearer', @admin_id, @admin_id),
(@company_id, 'Samwise Gamgee', 'Rope bearer', @admin_id, @admin_id),
(@company_id, 'Peregrin Took',  'Ent rider',   @admin_id, @admin_id);

有没有办法在 PostgreSQL 中实现类似的东西?

我看过的:

  • psql 的 session 变量(带有 \set ):不能用于存储查询结果
  • plpgsql:只能在过程中使用(我们仍在运行 8.4)
  • 临时表:如果不创建丑陋和复杂的语句,我不知道如何使用它们

如果没有 Postgres 的直接等价物,您认为生成此类更新文件的最不笨拙的方法是什么?

最佳答案

在 SELECT 中使用 VALUES(),这应该有效:

INSERT INTO employees (
    company_id,
    name,
    position,
    created_by,
    last_modified_by
)
SELECT
    (SELECT id FROM companies WHERE name = 'Acme Fellowship'),
    name,
    position,
    (SELECT id FROM users WHERE login = 'admin'),
    (SELECT id FROM users WHERE login = 'admin')
FROM
    (VALUES -- all your new content here
        ('Frodo Baggins',  'Ring bearer'), 
        ('Samwise Gamgee', 'Rope bearer'), 
        ('Peregrin Took',  'Ent rider')
    ) content(name, position); -- use some aliases to make it readable

关于mysql - 在 PostgreSQL 中替代 MySQL 的变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8767756/

相关文章:

mysql - 需要添加什么索引才能使该查询正常工作?

php - 我的 LOAD DATA INFILE 语法有什么问题?

postgresql - Ubuntu 中 PostgreSQL 数据库的自动备份

c# - 赋值不会使用 lambda 表达式修改 List ForEach 函数中的变量

sql - MySQL喜欢在()?

mysql - 基于一天的开始日期和结束日期的Django过滤器

postgresql - with isolation level = serializable Postgres 会自动重启失败的事务还是我必须自己做

ruby-on-rails - 使用 ActiveRecord 更新 Postgres JSON 字段

html - 向变量添加内容时如何添加新行

java - 我如何配置我的 .htaccess 文件,以便对 myurl.com/imageX.bmp(其中 X 是某个整数)的查询都提供相同的图像?