向H2数据库中的所有表添加列而不手动列出表
Posted
技术标签:
【中文标题】向H2数据库中的所有表添加列而不手动列出表【英文标题】:Add columns to all tables in H2 database without manually listing tables 【发布时间】:2017-09-27 11:17:43 【问题描述】:我有一个包含大约 70 个表的 PostgreSQL 数据库,我想为每个表添加两列,created_by
和 updated_by
。由于我们使用的是 Liquibase,因此我编写了一个在 PostgreSQL 中运行良好的更新脚本:
DO $$
DECLARE
tables CURSOR FOR
SELECT tablename
FROM pg_tables
WHERE schemaname = 'myschema'
ORDER BY tablename;
BEGIN
FOR table_record IN tables LOOP
EXECUTE
'ALTER TABLE ' || table_record.tablename || ' ADD COLUMN created_by BIGINT; ' ||
'ALTER TABLE ' || table_record.tablename || ' ADD COLUMN updated_by BIGINT;';
END LOOP;
END$$;
但是,对于集成测试,我们使用的是 H2 内存数据库,它不接受此 SQL,即使在 PostgreSQL 兼容模式下也是如此。 From this question,我知道如何选择所有表:
SELECT * FROM INFORMATION_SCHEMA.TABLES
但这对myschema
也有效吗?有没有办法存储结果并循环它们以添加列?如答案中所述,我也不明白如何使用或编写准备好的语句。
基本问题是:如何在不手动列出所有表的情况下为 H2 数据库编写等效的更新脚本?
【问题讨论】:
【参考方案1】:我还没有找到使用 H2 语法的方法。相反,我使用 SQL 使用 PostgreSQL 语法创建适当的查询:
SELECT 'ALTER TABLE ' || tablename || ' ADD COLUMN created_by BIGINT; ' ||
'ALTER TABLE ' || tablename || ' ADD COLUMN updated_by BIGINT;'
FROM pg_tables
WHERE schemaname = 'myschema'
ORDER BY tablename;
这将返回所有表的ALTER TABLE
查询列表,例如:
ALTER TABLE first_table ADD COLUMN created_by BIGINT;
ALTER TABLE first_table ADD COLUMN updated_by BIGINT;
这不适用于一组变化的表,但我只需要为一组固定的表执行此操作,因此它适用于我的情况。
(我在连接到我的 PostgreSQL 数据库的 SQL Workbench 中执行了查询。结果视图列出了已创建的查询,然后可以将它们复制到在测试期间执行的脚本文件中。)
【讨论】:
【参考方案2】:试试这样的:-)
DECLARE @Schema VARCHAR(20),
@Table VARCHAR(50),
@Query VARCHAR(4000),
@Column VARCHAR(100) = 'Column',
@Column_props VARCHAR(1000) = 'INT NOT NULL DEFAULT 0'
DECLARE c_cursor CURSOR FAST_FORWARD LOCAL FOR
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE
TABLE_TYPE='BASE TABLE'
OPEN c_cursor
FETCH NEXT FROM c_cursor INTO @Schema, @Table
WHILE @@FETCH_STATUS = 0 BEGIN
SET @Query = '
IF COL_LENGTH('''+@Schema+'.'+@Table+''', '''+@Column+''') IS NULL BEGIN
ALTER TABLE '+@Schema+'.'+@Table+'
ADD ['+@Column+'] '+@Column_props+'
END'
EXEC(@Query)
FETCH NEXT FROM c_cursor INTO @Schema, @Table
END
CLOSE c_cursor
DEALLOCATE c_cursor
【讨论】:
我没有使用 Postgre 的经验。这将是我在 MSSQL 上的解决方案 实际上,我需要它用于 H2。执行这个给我Syntax error in SQL statement: "..." expected "OR, FORCE, VIEW, ALIAS, SEQUENCE, USER, TRIGGER, ROLE, SCHEMA, CONSTANT, DOMAIN, TYPE, DATATYPE, AGGREGATE, LINKED, MEMORY, CACHED, LOCAL, GLOBAL, TEMP, TEMPORARY, TABLE, PRIMARY, UNIQUE, HASH, SPATIAL, INDEX";
我在 while 循环中错过了“获取下一个”。它现在已编辑。但我认为这不是你的问题.. sry,不太了解 h2 db 系统以上是关于向H2数据库中的所有表添加列而不手动列出表的主要内容,如果未能解决你的问题,请参考以下文章
如何使用Scala的DataFrame比较表中的每一列而不关心列是啥? [重复]