簡體   English   中英

將SQL Server查詢轉換為Oracle

[英]Converting SQL Server Query to Oracle

我有下面顯示的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;

因此,正如我所期望的那樣,經過一整天的斗爭並最終放棄並尋求幫助,我有了答案。 下面的查詢有效,但是,如果您有改進或建設性的批評,請分享我所說的,我正在嘗試學習。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM