SQL server函式轉Oracle問題之一,強行使用臨時表
阿新 • • 發佈:2021-01-05
SQL server函式轉Oracle問題之一,強行使用臨時表
1.工作中遇見的問題,背景是客戶的資料庫遷移,SQL server遷到Oracle。網上沒有對應的辦法,也不知對不對,至少不報BUG了,分享給大家
流程如下圖
這種建立方法百度“Oracle函式返回結果集(或臨時表)”有一堆,不重複說了。
注意:
臨時表函式中還要定義,格式如下:
(就像JAVA的定義)
然後剩餘步驟:
sqlserver原始碼:
CREATE function [dbo].[fn_g_CompareAllData](@pk_corp varchar(20),@BeginDate datetime,@EndDate datetime) returns @tem table ( SN bigint, --csalereceiveid char(20), --發貨單主鍵 vreceivecode char(30), --發貨單號 nnumber decimal(20,0), --數量 ntotaloutinvnum decimal(20,0), --數量 ntotaltransnum decimal(20,0), --累計運輸數量 --csaleid char(20), --發貨單主鍵 --pk_transport_h char(20), --運輸單主鍵 vbillcode_t char(30), --運輸單號 ntotalnumber decimal(20,0), --存貨總數量 reserve5 decimal(20,0), --週轉桶數 --transportcode char(20), --運輸單主鍵 vbillcode_r char(30), --回收單號 ntotalnumber2 numeric(28,0), --發貨單數量 backwaternum numeric(28,0), --退水數量 exwaternum numeric(28,0), --換水數量 yabucketnum numeric(28,0), --押退桶數量 getbucketnum numeric(28,0), --借/還桶數量 sendbucketnum numeric(28,0), --贈桶數量 backbucketnum numeric(28,0), --回桶數量 notclearnum numeric(28,0) --車輛未結清數量 ) begin --set @pk_corp = '3001' --set @BeginDate = '2013-08-01' --set @EndDate = '2013-08-11' set @pk_corp = (select top 1 pk_corp from bd_corp where unitcode = @pk_corp); declare @All table ( SN bigint identity(1,1), csalereceiveid char(20), --發貨單主鍵 vreceivecode char(30), --發貨單號 nnumber decimal(20,0), --數量 ntotaloutinvnum decimal(20,0), --數量 ntotaltransnum decimal(20,0), --累計運輸數量 csaleid char(20), --發貨單主鍵 pk_transport_h char(20), --運輸單主鍵 vbillcode_t char(30), --運輸單號 ntotalnumber decimal(20,0), --存貨總數量 reserve5 decimal(20,0), --週轉桶數 transportcode char(20), --運輸單主鍵 vbillcode_r char(30), --回收單號 ntotalnumber2 numeric(28,0), --發貨單數量 backwaternum numeric(28,0), --退水數量 exwaternum numeric(28,0), --換水數量 yabucketnum numeric(28,0), --押退桶數量 getbucketnum numeric(28,0), --借/還桶數量 sendbucketnum numeric(28,0), --贈桶數量 backbucketnum numeric(28,0), --回桶數量 notclearnum numeric(28,0) --車輛未結清數量 ); with so_salereceive_w as ( select b.csalereceiveid, b.vreceivecode, sum(c.nnumber) as nnumber, sum(c.ntotaloutinvnum) as ntotaloutinvnum, sum(c.ntotaltransnum) as ntotaltransnum from so_salereceive b with(nolock) inner join so_salereceive_b c with(nolock) on b.csalereceiveid = c.csalereceiveid inner join bd_invbasdoc d with(nolock) on c.cinvbasdocid = d.pk_invbasdoc inner join bd_invcl e with(nolock) on d.pk_invcl = e.pk_invcl where e.invclassname = '產成品' and b.pk_corp = @pk_corp and b.dapprovedate between @BeginDate and @EndDate and IsNull(b.dr,0) = 0 group by b.csalereceiveid,b.vreceivecode ), transport_w as ( select a.csaleid, a.pk_transport_h, b.vbillcode, sum(a.ntotalnumber) as ntotalnumber, sum(a.reserve5) as reserve5 from lbs_transport_b a with(nolock) inner join lbs_transport_h b with(nolock) on a.pk_transport_h = b.pk_transport_h inner join so_salereceive_w c with(nolock) on c.csalereceiveid = a.csaleid where IsNull(b.dr,0) = 0 group by a.csaleid,a.pk_transport_h,b.vbillcode ), tempReceipt_w as ( select distinct b.pk_receivebill_h,b.transportcode,b.vbillcode from lbs_receivebill_h b with(nolock) inner join transport_w c with(nolock) on c.pk_transport_h = b.transportcode where IsNull(b.dr,0) = 0 ), Receive_w as ( select b.transportcode, b.vbillcode, sum(a.ntotalnumber) as ntotalnumber, --發貨單數量 sum(backwaternum) as backwaternum, --退水數量 sum(exwaternum) as exwaternum, --換水數量 sum(yabucketnum) as yabucketnum, --押退桶數量 sum(getbucketnum) as getbucketnum, --借/還桶數量 sum(sendbucketnum) as sendbucketnum, --贈桶數量 sum(backbucketnum) as backbucketnum, --回桶數量 sum(notclearnum) as notclearnum --車輛未結清數量 from lbs_receivebill_b a with(nolock) inner join tempReceipt_w b with(nolock) on a.pk_receivebill_h = b.pk_receivebill_h group by b.transportcode,b.vbillcode ) insert @All ( --發貨單 --csalereceiveid, --發貨單主鍵 vreceivecode, nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 --運輸單 --csaleid, --發貨單主鍵 --pk_transport_h , --運輸單主鍵 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 --回桶單 --transportcode, --運輸單主鍵 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 ) select a.vreceivecode, a.nnumber, --數量 a.ntotaloutinvnum, --數量 a.ntotaltransnum, ----------------------- b.vbillcode, b.ntotalnumber, --存貨總數量 b.reserve5, --週轉桶數 ----------------------- c.vbillcode, c.ntotalnumber, --發貨單數量 c.backwaternum, --退水數量 c.exwaternum, --換水數量 c.yabucketnum, --押退桶數量 c.getbucketnum, --借/還桶數量 c.sendbucketnum, --贈桶數量 c.backbucketnum, --回桶數量 c.notclearnum from so_salereceive_w a with(nolock) left join transport_w b with(nolock) on a.csalereceiveid = b.csaleid left join Receive_w c with(nolock) on b.pk_transport_h = c.transportcode order by a.csalereceiveid,b.pk_transport_h,c.transportcode ; update @All set nnumber = null,ntotaloutinvnum = null,ntotaltransnum = null from @All ta where SN <> (select min(SN) from @All where csalereceiveid = ta.csalereceiveid) ; update @All set ntotalnumber = null,reserve5 = null from @All ta where SN <> (select min(SN) from @All where pk_transport_h = ta.pk_transport_h and csaleid = ta.csaleid) ; insert @tem ( SN, --發貨單 --csalereceiveid, --發貨單主鍵 vreceivecode , --發貨單號 nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 --運輸單 --csaleid, --發貨單主鍵 --pk_transport_h , --運輸單主鍵 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 --回桶單 --transportcode, --運輸單主鍵 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 ) select SN, --發貨單 --csalereceiveid, --發貨單主鍵 vreceivecode , --發貨單號 nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 --運輸單 --csaleid, --發貨單主鍵 --pk_transport_h , --運輸單主鍵 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 --回桶單 --transportcode, --運輸單主鍵 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 from @All order by SN; return; end
轉化後的Oracle:
3, fn_g_CompareAllData --√ Oracler : create sequence fn_g_Compare_sq maxvalue 99999999999999999999 increment by 1 start with 1; --步長為1 create or replace type all_obj_type as object( SN number(20), --發貨單主鍵 csalereceiveid varchar2(20), --發貨單主鍵 vreceivecode varchar2 (30), --發貨單號 nnumber number (20,0), --數量 ntotaloutinvnum number (20,0), --數量 ntotaltransnum number (20,0), --累計運輸數量 csaleid varchar2 (20), --發貨單主鍵 pk_transport_h number (20), --運輸單主鍵 vbillcode_t number (30), --運輸單號 ntotalnumber number (20,0), --存貨總數量 reserve5 number (20,0), --週轉桶數 transportcode varchar2 (20), --運輸單主鍵 vbillcode_r varchar2 (30), --回收單號 ntotalnumber2 number (28,0), --發貨單數量 backwaternum number(28,0), --退水數量 exwaternum number (28,0), --換水數量 yabucketnum number (28,0), --押退桶數量 getbucketnum number (28,0), --借/還桶數量 sendbucketnum number (28,0), --贈桶數量 backbucketnum number (28,0), --回桶數量 notclearnum number (28,0) --車輛未結清數量 ); CREATE OR REPLACE TYPE all_tab_type IS TABLE OF all_obj_type; create or replace type tem_obj_type as object( SN number, --csalereceiveid char(20), --發貨單主鍵 vreceivecode varchar2 (30), --發貨單號 nnumber number (20,0), --數量 ntotaloutinvnum number (20,0), --數量 ntotaltransnum number (20,0), --累計運輸數量 vbillcode_t varchar2 (30), --運輸單號 ntotalnumber number (20,0), --存貨總數量 reserve5 number (20,0), --週轉桶數 vbillcode_r varchar2 (30), --回收單號 ntotalnumber2 number (28,0), --發貨單數量 backwaternum number (28,0), --退水數量 exwaternum number (28,0), --換水數量 yabucketnum number (28,0), --押退桶數量 getbucketnum number (28,0), --借/還桶數量 sendbucketnum number (28,0), --贈桶數量 backbucketnum number (28,0), --回桶數量 notclearnum number (28,0) --車輛未結清數量 ); CREATE OR REPLACE TYPE tem_tab_type IS TABLE OF tem_obj_type; --定義工具類表,之後清除裡面的資料 create table all_tab_linshi( SN number(20), csalereceiveid varchar2(20), vreceivecode varchar2 (30), nnumber number (20,0), ntotaloutinvnum number (20,0), ntotaltransnum number (20,0), csaleid varchar2 (20), pk_transport_h number (20), vbillcode_t number (30), ntotalnumber number (20,0), reserve5 number (20,0), transportcode varchar2 (20), vbillcode_r varchar2 (30), ntotalnumber2 number (28,0), backwaternum number(28,0), exwaternum number (28,0), yabucketnum number (28,0), getbucketnum number (28,0), sendbucketnum number (28,0), backbucketnum number (28,0), notclearnum number (28,0) ); Create table tem_tab_linshi( SN number, vreceivecode varchar2 (30), --發貨單號 nnumber number (20,0), --數量 ntotaloutinvnum number (20,0), --數量 ntotaltransnum number (20,0), --累計運輸數量 vbillcode_t varchar2 (30), --運輸單號 ntotalnumber number (20,0), --存貨總數量 reserve5 number (20,0), --週轉桶數 vbillcode_r varchar2 (30), --回收單號 ntotalnumber2 number (28,0), --發貨單數量 backwaternum number (28,0), --退水數量 exwaternum number (28,0), --換水數量 yabucketnum number (28,0), --押退桶數量 getbucketnum number (28,0), --借/還桶數量 sendbucketnum number (28,0), --贈桶數量 backbucketnum number (28,0), --回桶數量 notclearnum number (28,0) ); --序列預備的函式 create or replace function get_fn_g_Compare_sq return number is seq_val number ; begin execute immediate 'select fn_g_Compare_sq. NEXTVAL from dual' into seq_val ; return seq_val ; end get_fn_g_Compare_sq; --函式本體 CREATE OR REPLACE function fn_g_CompareAllData(pk_corp_dec in varchar2,BeginDate_dec in date,EndDate_dec in date) return tem_tab_type IS tab_tem tem_tab_type:= tem_tab_type(); v_pk_corp varchar2(20); begin execute immediate 'Create Global Temporary Table tab_f_lbs_cuacc ( custcode varchar2(40), custname varchar2(200), respname varchar2(200), pccode varchar2(40), pcname varchar2(40), skmny number(20,2), ysmny number(20,2), somny number(20,2), allowmny number(20,2) ) On Commit Delete Rows '; select pk_corp into v_pk_corp from( select pk_corp from bd_corp where unitcode = pk_corp_dec) where rownum=1; --這是分割線 insert into all_tab_linshi ( Sn, vreceivecode, nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 ) with so_salereceive_w as ( select b.csalereceiveid, b.vreceivecode, sum(c.nnumber) as nnumber, sum(c.ntotaloutinvnum) as ntotaloutinvnum, sum(c.ntotaltransnum) as ntotaltransnum from so_salereceive b inner join so_salereceive_b c on b.csalereceiveid = c.csalereceiveid inner join bd_invbasdoc d on c.cinvbasdocid = d.pk_invbasdoc inner join bd_invcl e on d.pk_invcl = e.pk_invcl where e.invclassname = '產成品' and b.pk_corp = v_pk_corp and b.dapprovedate between BeginDate_dec and EndDate_dec and nvl(b.dr,0) = 0 group by b.csalereceiveid,b.vreceivecode), transport_w as ( select a.csaleid, a.pk_transport_h, b.vbillcode, sum(a.ntotalnumber) as ntotalnumber, sum(a.reserve5) as reserve5 from lbs_transport_b a inner join lbs_transport_h b on a.pk_transport_h = b.pk_transport_h inner join so_salereceive_w c on c.csalereceiveid = a.csaleid where nvl(b.dr,0) = 0 group by a.csaleid,a.pk_transport_h,b.vbillcode ), tempReceipt_w as ( select distinct b.pk_receivebill_h,b.transportcode,b.vbillcode from lbs_receivebill_h b inner join transport_w c on c.pk_transport_h = b.transportcode where nvl(b.dr,0) = 0 ), Receive_w as ( select b.transportcode, b.vbillcode, sum(a.ntotalnumber) as ntotalnumber, --發貨單數量 sum(backwaternum) as backwaternum, --退水數量 sum(exwaternum) as exwaternum, --換水數量 sum(yabucketnum) as yabucketnum, --押退桶數量 sum(getbucketnum) as getbucketnum, --借/還桶數量 sum(sendbucketnum) as sendbucketnum, --贈桶數量 sum(backbucketnum) as backbucketnum, --回桶數量 sum(notclearnum) as notclearnum --車輛未結清數量 from lbs_receivebill_b a inner join tempReceipt_w b on a.pk_receivebill_h = b.pk_receivebill_h group by b.transportcode,b.vbillcode) Select get_fn_g_Compare_sq, a.vreceivecode, a.nnumber, --數量 a.ntotaloutinvnum, --數量 a.ntotaltransnum, ----------------------- b.vbillcode, b.ntotalnumber, --存貨總數量 b.reserve5, --週轉桶數 ----------------------- c.vbillcode, c.ntotalnumber, --發貨單數量 c.backwaternum, --退水數量 c.exwaternum, --換水數量 c.yabucketnum, --押退桶數量 c.getbucketnum, --借/還桶數量 c.sendbucketnum, --贈桶數量 c.backbucketnum, --回桶數量 c.notclearnum from so_salereceive_w a left join transport_w b on a.csalereceiveid = b.csaleid left join Receive_w c on b.pk_transport_h = c.transportcode order by a.csalereceiveid,b.pk_transport_h,c.transportcode ; update all_tab_linshi set nnumber = null,ntotaloutinvnum = null,ntotaltransnum = null where SN != (select min(SN) from all_tab_linshi); update all_tab_linshi set ntotalnumber = null,reserve5 = null where SN != (select min(SN) from all_tab_linshi); insert into tem_tab_linshi ( SN, vreceivecode , --發貨單號 nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 ) select SN, vreceivecode , --發貨單號 nnumber, --數量 ntotaloutinvnum, --數量 ntotaltransnum, --累計運輸數量 vbillcode_t, ntotalnumber, --存貨總數量 reserve5, --週轉桶數 vbillcode_r, ntotalnumber2, --發貨單數量 backwaternum, --退水數量 exwaternum, --換水數量 yabucketnum, --押退桶數量 getbucketnum, --借/還桶數量 sendbucketnum, --贈桶數量 backbucketnum, --回桶數量 notclearnum --車輛未結清數量 from all_tab_linshi order by SN; --將臨時表資料插入函式中的自定義表, --然後情況臨時表資料,返回自定義表 for i in (SELECT Sn,vreceivecode,nnumber,ntotaloutinvnum,ntotaltransnum, vbillcode_t,ntotalnumber,reserve5,vbillcode_r,ntotalnumber2, backwaternum,exwaternum,yabucketnum,getbucketnum,sendbucketnum, backbucketnum,notclearnum FROM tem_tab_linshi) loop tab_tem.extend; tab_tem (tab_tem.count) := tem_obj_type (i.Sn,i.vreceivecode,i.nnumber,i.ntotaloutinvnum,i.ntotaltransnum, i.vbillcode_t,i.ntotalnumber,i.reserve5,i.vbillcode_r, i.ntotalnumber2,i.backwaternum,i.exwaternum,i.yabucketnum, i.getbucketnum,i.sendbucketnum,i.backbucketnum,i.notclearnum ); end loop; execute immediate ' truncate table tem_tab_linshi '; execute immediate ' truncate table all_tab_linshi '; return tab_tem; end ;
有點隨意,希望能給遇見同樣問題的朋友幫助,可以私信我,不過新手很菜,只能幫一些。
(網上也有很多人不建議這種方法,如果想返回結果集,最好使用遊標。但我還不熟悉遊標,也懇請看到的大神給我建議)