【问题标题】:confused on how to properly use %rowtype for many tables对如何为许多表正确使用 %rowtype 感到困惑
【发布时间】:2015-05-05 15:46:10
【问题描述】:

我正在尝试从其他几个表创建一个国家数据派生表。这些表看起来像这样:

Countries 
ID | Name

Country_demographics
ID | date | Population | urban_pop | birth_rate

country_financials
ID | date | GDP | GDP_per_capita

现在,我正在尝试使用

New_Table
ID | Name | date | population | urban_pop | birth_rate | gdp | gdp_per_capita

我有一个存储过程,目前看起来像这样:

CREATE OR REPLEACE PROCEDURE SP_COUNTRY (
chunkSize IN INT
) AS

    --create tables to hold IDs and stats
        TYPE idTable IS TABLE OF COUNTRIES.ID%TYPE;
        TYPE dateTable IS TABLE OF COUNTRY_DEMOGRAPHICS.EVALUATION_DATE%TYPE;
        TYPE totPopTable IS TABLE OF COUNTRY_DEMOGRAPHICS.POPULATION_TOTAL_COUNT%TYPE;
        TYPE urbanPopTable IS TABLE OF COUNTRY_DEMOGRAPHICS.POPULATION_URBAN_COUNT%TYPE;
        --constructors
        ids idTable;
        dates dateTable;
        totpop totPopTable;
        urbanpop urbanPopTable;


    --cursors
    CURSOR countryCur IS
      SELECT c.ID,cd.EVALUATION_DATE,cd.POPULATION_TOTAL_COUNT,cd.POPULATION_URBAN_COUNT
      FROM COUNTRIES c,COUNTRY_DEMOGRAPHICS cd
      WHERE c.id=cd.COUNTRY_ID
      ORDER BY ID,EVALUATION_DATE;

    BEGIN
      dbms_output.enable(999999);
      --open cursor
      OPEN countryCur;
      LOOP
        --fetch and bulk collect
        FETCH countryCur BULK COLLECT INTO ids,dates,totpop,urbanpop
        LIMIT chunkSize;
        --loop over collections
        FOR j in ids.FIRST..ids.LAST
        LOOP
          --populate record
          country.COUNTRY_ID := ids(j);
          country.EVALUATION_DATE := dates(j);
          country.POPULATION_TOTAL_COUNT := totpop(j);
          country.POPULATION_URBAN_COUNT := urbanpop(j);
          --update/insert table with record (much confusion here on how to update/insert and check if already exists in derived table..)
          UPDATE NEW_TABLE SET ROW = country WHERE COUNTRY_ID = ids(j);
          dbms_output.put_line('id: ' || country.COUNTRY_ID || '  date: ' || country.EVALUATION_DATE);
          dbms_output.put_line('     pop: ' || country.POPULATION_TOTAL_COUNT || '  urban: ' || country.POPULATION_URBAN_COUNT);
        END LOOP;
      END LOOP;
      --close cursor
      CLOSE countryCur;
    END;

如您所见,我为每条数据使用不同的表类型。然后我计划制作一个循环,然后在我的 new_table 中插入/更新。我认为必须有更好的方法来使用 %rowtype 执行此操作,或者创建记录并插入记录?我不确定

【问题讨论】:

    标签: plsql cursor rowtype


    【解决方案1】:

    除非我通过简化而遗漏了一些东西,并且假设 cd.date 和 cf.date 是相等的,否则这应该可以工作:

    INSERT INTO NEW_TABLE (ID, Name, date, population, urban_pop, birth_rate, gdp, gdp_per_capita)
    values
    (select c.id, c.name, cd.date, 
            cd.population, cd.urban_pop, cd.birthrate,
            cf.gdp, cf.gdp_per_capita)
    from Countries c, country_demographics cd, country_financials cf 
    where c.id = cd.id
    and   cd.id = cf.id);
    

    编辑:根据主键是否存在,使用 MERGE 语句更新或插入:

    MERGE INTO NEW_TABLE nt
        USING ( select c.id, c.name, cd.date, 
                       cd.population, cd.urban_pop, cd.birthrate,
                       cf.gdp, cf.gdp_per_capita
                from Countries c, country_demographics cd, country_financials cf 
                where c.id = cd.id
                and   cd.id = cf.id ) a
        ON (nt.id = a.id )
        WHEN MATCHED THEN 
          UPDATE SET nt.Name           = a.Name,
                     nt.date           = a.date,
                     nt.population     = a.population,
                     nt.urban_pop      = a.urban_pop,
                     nt.birth_rate     = a.birth_rate,
                     nt.gdp            = a.gdp,
                     nt.gdp_per_capita = a.gdp_per_capita
        WHEN NOT MATCHED THEN 
          INSERT (ID, Name, date, population, urban_pop, birth_rate, gdp, gdp_per_capita)
          VALUES (a.id, a.Name, a.date, a.population, a.urban_pop, a.birth_rate, a.gdp, a.gdp_per_capita);
    

    【讨论】:

    • 感谢您的回复,但我正在使用存储过程,因为我希望能够运行它来根据不时填充在其他表中的数据更新我的 new_table。
    • 所以放到一个存储过程中。 :-) 可以从您设置为每天运行的数据库作业中调用它,以使其保持最新。
    • 哇,这比我拥有的更干净、更快速而且......不同。感谢您的答复。使用 join 语句而不是“where”是否有优势?
    猜你喜欢
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-28
    • 1970-01-01
    相关资源
    最近更新 更多