【问题标题】:Add columns to all tables in H2 database without manually listing tables向H2数据库中的所有表添加列而不手动列出表
【发布时间】:2017-09-27 11:17:43
【问题描述】:

我有一个包含大约 70 个表的 PostgreSQL 数据库,我想为每个表添加两列,created_byupdated_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 数据库编写等效的更新脚本?

【问题讨论】:

    标签: sql 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 系统
      猜你喜欢
      • 2021-06-08
      • 2013-06-11
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 2019-05-04
      • 2013-10-05
      相关资源
      最近更新 更多