1. 程式人生 > 其它 >微信小程式圖片上傳

微信小程式圖片上傳

此文轉載自:https://blog.csdn.net/qq_40791652/article/details/112213180#commentBox

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 ; 的方法呼叫