react 移動端簽名實現
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
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 ;
有點隨意,希望能給遇見同樣問題的朋友幫助,可以私信我,不過新手很菜,只能幫一些。
(網上也有很多人不建議這種方法,如果想返回結果集,最好使用遊標。但我還不熟悉遊標,也懇請看到的大神給我建議)
然而這樣的函式不報錯,但使用 select 函式名(形參。。。) from dual 呼叫時卻報查詢或者DML中不允許執行DDL。。。。。。這方法不行
----分割線
PRAGMA AUTONOMOUS_TRANSACTION;
上面那一句,加在函式或者儲存過程的第一個BEGIN之前,然後每一個函式或儲存過程中的DML後面新增一個 commit;
如下面兩個程式碼:
PRAGMA AUTONOMOUS_TRANSACTION;
begin
execute immediate
' delete so_salereceive_linshi ';
Commit;
execute immediate
' delete temReceipt_linshi ';
Commit;
execute immediate
' delete temReceipt2_linshi ';
Commit;
原理大概是Oracle中函式或者儲存過程不允許DDL,DML的話要提交,PRAGMA AUTONOMOUS_TRANSACTION; 這句語句宣告函式或儲存過程為自治事務,然後使用delete 表名代替 truncate table 表名。
改後之後的函式可以用下面語句呼叫測試:
select 函式名(形參,形參。。。) from dual ; 的方法呼叫