简体   繁体   中英

Converting SQL Server Query to Oracle

I have the SQL Server query shown below and I am trying to get it to work on Oracle. I have done some looking but am new to Oracle so I am not even sure what I should be looking for. I am hoping that I can make the a query to run adhoc not necessarily a procedure. The basic concept is the following:

  1. Create a temporary table to hold data to be totaled.
  2. Create a date table to get a list of dates.
  3. Build a dynamic query to insert data into the temporary table.
  4. Execute the dynamic query.
  5. Select the summary from the temporary table.
  6. Drop the temporary table

Please remember, I am new to Oracle and I have done some looking. I know that the variables and aliases must be formatted differently and can get the date table but I am not sure the proper Oracle way to create and execute dynamic queries where the table name is the dynamic part. I can create the dynamic string with the correct table name but don't know how to execute it. I have seen some examples but none of them seem to make sense to me for what I am trying to do.

-- 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;

What I have done in the past is create a bash script which would do the looping through each date and then used the script to summarize the output. This time however I am trying to learn something and I know that there has to be a way to do this in SQL in Oracle.

I appreciate any help or assistance and hope I have explained this well enough.

-- 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;

So as I expected, after fighting this all day and finally giving up and asking for help I have an answer. The query below works however if you have improvements or constructive criticism please share as I said, I am trying to learn.

-- 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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM