【问题标题】:Converting SQL Server Query to Oracle将 SQL Server 查询转换为 Oracle
【发布时间】:2018-07-20 00:34:07
【问题描述】:

我有如下所示的 SQL Server 查询,我正在尝试让它在 Oracle 上运行。我做了一些查找,但对 Oracle 还是新手,所以我什至不确定我应该寻找什么。我希望我可以进行查询以运行临时而不一定是一个过程。基本概念如下:

  1. 创建一个临时表来保存要汇总的数据。
  2. 创建日期表以获取日期列表。
  3. 构建动态查询以将数据插入临时表。
  4. 执行动态查询。
  5. 从临时表中选择摘要。
  6. 删除临时表

请记住,我是 Oracle 的新手,我已经做了一些查找。我知道变量和别名的格式必须不同,并且可以获取日期表,但我不确定创建和执行动态查询的正确 Oracle 方法,其中表名是动态部分。我可以使用正确的表名创建动态字符串,但不知道如何执行它。我看过一些例子,但对我来说似乎没有一个对我想要做的有意义。

-- Oracle query for dates
with dt (d) as (
    select last_day(add_months(sysdate,-2))+1 + rownum - 1 
    from all_objects 
    where rownum <= sysdate-last_day(add_months(sysdate,-2))+1+1
)
select 'insert into #tt (cnt, eem, ers, sts) (
        select count(1), eem_id, ers_id, sts_id
        from event_error' || to_char(D, 'ddmmyy') || ' eve
        group by sts_id, eem_id, ers_id); ' "QRY"
from dt;

我过去所做的是创建一个 bash 脚本,该脚本将循环遍历每个日期,然后使用该脚本来总结输出。然而这一次我正在尝试学习一些东西,并且我知道在 Oracle 中的 SQL 中必须有一种方法可以做到这一点。

感谢任何帮助或帮助,并希望我已经充分解释了这一点。

-- Working SQL Server query

-- declare variables
declare @query varchar(max);

-- create temporary table
create table #tt(cnt int, eem int, ers int, sts int);

-- get a list of dates to process
with dt (d) as 
(
    select dateadd(month, datediff(month, 0, getdate())-1, 0) as d

    union all

    select dateadd(dd, 1, d)
    from dt
    where dateadd(dd, 1, d) <= getdate()
)
-- build the dynamic query
select distinct
    @query = stuff ((select 'insert into #tt (cnt, eem, ers, sts) (
    select count(1), eem_id, ers_id, sts_id
    from event_error' + replace(convert(varchar(5), d, 103), '/', '') + right(year(d), 2) + ' (nolock) eve
    group by sts_id, eem_id, ers_id); '
        from dt for xml path, type).value(N'.[1]',N'nvarchar(max)')
    , 1, 1, N'')
from dt;

-- to execute the dynamic query
execute (@query);

-- query the temporary table
select
    [Stream] = sts.sts_name,
    [Count] = sum(eve.cnt),
    [Error Status] = ers.ers_name,
    [Error Number] = eem.eem_error_no,
    [Error Text] = eem.eem_error_text
from 
    #tt eve
inner join 
    event_error_message eem on eem.eem_id = eve.eem
inner join 
    error_status ers on ers.ers_id = eve.ers
inner join 
    stream_stage sts on sts.sts_id = eve.sts
group by 
    sts.sts_name, eem.eem_error_no, eem.eem_error_text, ers.ers_name
order by 
    sts.sts_name, eem.eem_error_no, ers.ers_name;

-- drop the temporary table
drop table #tt;

【问题讨论】:

    标签: sql oracle dynamic temporary


    【解决方案1】:

    所以正如我所料,经过一整天的战斗,最终放弃并寻求帮助,我得到了答案。下面的查询有效,但是如果您有改进或建设性的批评,请按照我所说的分享,我正在努力学习。

    -- create the temporary table
    create global temporary table my_tt (
      cnt   number
      , sts number
      , eem number
      , ers number
    )
    on commit delete rows;
    
    declare
        V_TABL_NM       ALL_TABLES.TABLE_NAME%TYPE;
        V_SQL           VARCHAR2(1024);
    begin
        for GET_TABL_LIST in (
            with dt (d) as (
                select last_day(add_months(sysdate,-2))+1 + rownum -1
                from all_objects 
                where rownum <= sysdate-last_day(add_months(sysdate,-2))
            )
            select 'event_error' || to_char(D, 'ddmmyy') TABLE_NAME from dt
        ) loop
            V_TABL_NM := GET_TABL_LIST.TABLE_NAME;
            V_SQL := 'insert into my_tt select count(1), sts_id, eem_id, ers_id from ' || V_TABL_NM || ' group by sts_id, eem_id, ers_id';
            execute immediate V_SQL;
        end loop;
    end;
    /
    -- the slash is important for the above statement to complete
    
    select
        sts.sts_name            "Stream"
        , sum(eve.cnt)          "Count"
        , ers.ers_name          "Error Status"
        , eem.eem_error_no      "Error Number"
        , eem.eem_error_text    "Error Text"
    from my_tt eve
    inner join event_error_message eem
        on eem.eem_id = eve.eem
    inner join error_status ers
        on ers.ers_id = eve.ers
    inner join stream_stage sts
        on sts.sts_id = eve.sts
    group by sts.sts_name, eem.eem_error_no, eem.eem_error_text, ers.ers_name
    order by sts.sts_name, eem.eem_error_no, ers.ers_name;
    
    -- drop the temporary table
    drop table my_tt purge;
    

    【讨论】:

    • 鉴于您是 Oracle 新手,您的动态代码看起来不错,除了使用一两个可以避免的额外变量。您也可以使用connect by loop 而不是selecting from all_objects - 只是在极少数情况下没有权限查看all_objects 等。
    猜你喜欢
    • 2016-07-29
    • 1970-01-01
    • 2022-01-12
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-01
    • 2017-06-03
    相关资源
    最近更新 更多