create or replace
PROCEDURE p_saveIssuerCinemaAdd_param(sheetId IN varchar2,issuerCinemaAddIds IN clob)  Authid Current_User AS
--sheetId 任务id  issuerCinemaAddIds 按上传影院列表
str_split ty_tbl_str_split;--影厅ids
str_filmType filmType_array;--影片类型
l_str   varchar2(4000);
is_jpeg number(1) :=0;
is_mpeg number(1) :=0;
equipIdCount number(10) :=0;
certificateIdCount number(10) :=0;
con number(10) :=0;
join_sql varchar2(4000);
BEGIN
--通过issuerCinemaAddIds找到所有的影院--execute immediate 'create global temporary table temp_cinema(id varchar2(32),cinemaId varchar2(32)) on commit delete ROWS';--建立临时表-- execute immediate 'create global temporary table temp_theater(id varchar2(32),theaterId varchar2(32)) on commit delete ROWS';--建立临时表
--找到符合条件的所有影院str_split :=fn_split(issuerCinemaAddIds,',');-- dbms_output.put_line('str_split.count影厅个数'||str_split.count);if(str_split.count >0) thenfor y in 1..str_split.count loopjoin_sql :='insert into T_ISSUER_CINEMA(ID,ISSUER_SKDM_RANGE_INFO_SHEET,CIENMA,sn,STARTTIME) select sys_guid(),'||''''||sheetId||''''||',c.cinema_id,sys_guid(),sysdate from t_issuer_cinema_add cc,t_cinema c where cc.id='||''''|| str_split(y).strValue||''''||' and cc.cinemaname=c.cinema and cc.cinemacode=c.cinema_code ';  dbms_output.put_line('T_ISSUER_CINEMA sql语句:'||join_sql);execute immediate join_sql;  --从t_issuer_cinema_add表里删除符合条件的记录join_sql :='delete from t_issuer_cinema_add cc where cc.id='||''''|| str_split(y).strValue||''''||'';execute immediate join_sql;end loop; end if;--过滤影片类型  select count(*) into con from t_skdmsheet_filmtype where skdmsheetid=sheetId;if(con>0) thenselect filmtypeid bulk collect into str_filmType from t_skdmsheet_filmtype where skdmsheetid=sheetId;for y in 1..con loopif(str_filmType(con)='MPEG2') thenis_mpeg :=1;end if;if(str_filmType(con)='JPEG2000') thenis_jpeg :=1;end if; if(str_filmType(con)='IMAX') thenis_jpeg :=1;end if;end loop;end if;--过滤影厅ID--影厅idsjoin_sql := 'insert into temp_theater(id,theaterId) select sys_guid(),m.THEATER_ID from v_certificate_theater m,T_ISSUER_CINEMA c where m.CINEMA_ID=c.cienma  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.THEATER_ID in (select theater_id from t_theater where theater_attribute in (select filmattribute from t_skdmsheet_attribute where skdmsheetid='||''''||sheetId||''''||')) group by m.THEATER_ID';dbms_output.put_line('theaterId_sql语句'||join_sql);execute immediate join_sql;   join_sql :='select count(*) from temp_theater';execute immediate join_sql into con;   dbms_output.put_line('符合条件的影厅个数:'||con);  --更新t_issuer_skdm_range_info_sheetif(is_jpeg=1) thenif(is_mpeg=0) then--c.cienma  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||'join_sql :='select count(distinct(m.equip_id)) from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and  m.is_jpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into equipIdCount;join_sql :='select count(distinct(vn.certificate_id)) from (select m.* from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c  where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))) vt,v_certificate_theater vn where vt.equip_id=vn.equip_id';execute immediate join_sql into certificateIdCount;dbms_output.put_line('设备ID'||equipIdCount);dbms_output.put_line('证书ID'||certificateIdCount);update t_issuer_skdm_range_info_sheet set EQUIP_NUM=nvl(EQUIP_NUM,0)+equipIdCount,CERTIFICATE_NUM=nvl(CERTIFICATE_NUM,0)+certificateIdCount where SHEET_ID=sheetId;--插入T_ISSUER_CINEMA_THEATERjoin_sql :='select count(*) from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into con;dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER'||con||'条数据');join_sql :='insert into T_ISSUER_CINEMA_THEATER(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4 from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER语句'||join_sql);execute immediate join_sql;join_sql :='insert into T_ISSUER_CINEMA_THEATER_PMP(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE,certificateId,equipId) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4,m.certificate_id,m.equip_id from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER_PMP语句'||join_sql);execute immediate join_sql;end if;if(is_mpeg=1) thenjoin_sql :='select count(distinct(m.equip_id)) from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and  m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into equipIdCount;join_sql :='select count(distinct(vn.certificate_id)) from (select m.* from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c  where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))) vt,v_certificate_theater vn where vt.equip_id=vn.equip_id';execute immediate join_sql into certificateIdCount;dbms_output.put_line('设备ID'||equipIdCount);dbms_output.put_line('证书ID'||certificateIdCount);update t_issuer_skdm_range_info_sheet set EQUIP_NUM=nvl(EQUIP_NUM,0)+equipIdCount,CERTIFICATE_NUM=nvl(CERTIFICATE_NUM,0)+certificateIdCount where SHEET_ID=sheetId;--插入T_ISSUER_CINEMA_THEATERjoin_sql :='select count(*) from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into con;-- dbms_output.put_line('插入T_ISSUER_CINEMA'||con||'条数据');--  join_sql :='insert into T_ISSUER_CINEMA(ID,ISSUER_SKDM_RANGE_INFO_SHEET,CIENMA,sn,STARTTIME) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,sys_guid(),sysdate from v_certificate_theater m,temp_theater_cinema theater where m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId  and m.cinema_id=theater.cinemaId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';-- dbms_output.put_line('插入T_ISSUER_CINEMA语句'||join_sql);-- execute immediate join_sql;dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER'||con||'条数据');join_sql :='insert into T_ISSUER_CINEMA_THEATER(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4 from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER语句'||join_sql);execute immediate join_sql;join_sql :='insert into T_ISSUER_CINEMA_THEATER_PMP(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE,certificateId,equipId) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4,m.certificate_id,m.equip_id from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER_PMP语句'||join_sql);execute immediate join_sql;end if;    end if;if(is_jpeg=0) thenif(is_mpeg=0) thennull;end if;if(is_mpeg=1) thenjoin_sql :='select count(distinct(m.equip_id)) from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into equipIdCount;join_sql :='select count(distinct(vn.certificate_id)) from (select m.* from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c  where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))) vt,v_certificate_theater vn where vt.equip_id=vn.equip_id';execute immediate join_sql into certificateIdCount;dbms_output.put_line('设备ID'||equipIdCount);dbms_output.put_line('证书ID'||certificateIdCount);update t_issuer_skdm_range_info_sheet set EQUIP_NUM=nvl(EQUIP_NUM,0)+equipIdCount,CERTIFICATE_NUM=nvl(CERTIFICATE_NUM,0)+certificateIdCount where SHEET_ID=sheetId;--插入T_ISSUER_CINEMA_THEATERjoin_sql :='select count(*) from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into con;-- dbms_output.put_line('插入T_ISSUER_CINEMA'||con||'条数据');--  join_sql :='insert into T_ISSUER_CINEMA(ID,ISSUER_SKDM_RANGE_INFO_SHEET,CIENMA,sn,STARTTIME) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,sys_guid(),sysdate from v_certificate_theater m,temp_theater_cinema theater where m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId  and m.cinema_id=theater.cinemaId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';-- dbms_output.put_line('插入T_ISSUER_CINEMA语句'||join_sql);-- execute immediate join_sql;dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER'||con||'条数据');join_sql :='insert into T_ISSUER_CINEMA_THEATER(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4 from v_certificate_theater m,temp_theater theater ,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER语句'||join_sql);execute immediate join_sql;join_sql :='insert into T_ISSUER_CINEMA_THEATER_PMP(ID,ISSUER_SKDM_RANGE_INFO_SHEET,ISSUER_CINEMA,ISSUER_THEATER,IFTHREEORTWO,ISSUERTYPE,certificateId,equipId) select sys_guid(),'||''''||sheetId||''''||',m.cinema_id,m.theater_id,nvl(m.THEATER_ATTRIBUTE,0),4,m.certificate_id,m.equip_id from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where  c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';dbms_output.put_line('插入T_ISSUER_CINEMA_THEATER_PMP语句'||join_sql);execute immediate join_sql;end if;    end if;commit;-- execute immediate 'drop table temp_cinema'; -- execute immediate 'drop table temp_theater'; exception when others thenl_str:=sqlerrm(sqlcode);dbms_output.put_line(l_str);
end p_saveIssuerCinemaAdd_param;

以上是实际的一个存储过程,为了方便理解,我使用上面的存储过程记录一下编写过程中的一些问题。

  • 存储过程的声明部分可以看到俩个自己定义的数据类型
str_split ty_tbl_str_split;--影厅ids
str_filmType filmType_array;--影片类型

oracle支持自定义数据类型以满足实际需要,下面展示上面俩个类型的定义sql

create or replace
type     t_array IS TABLE OF VARCHAR2(32) ;

定义了一个可变数组,数组元素是一个32字节的字符串类型

create or replace TYPE ty_row_str_split as object (strValue VARCHAR2 (4000));

定义了一个对象,对象有一个字符串属性

create or replace TYPE     ty_tbl_str_split IS TABLE OF ty_row_str_split;

定义一个可变数组,里面的元素是上面的自定义对象

  • 常见的错误

1:

join_sql :='select count(distinct(m.equip_id)) from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and  m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))';execute immediate join_sql into equipIdCount;

如果使用动态拼接sql,

c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||'

id的拼接要记得加上‘’,不让回报“标识符过长的错误”(当然标识符过长还有可能是其他原因,比如字符长度超过了4000字节)

冒号的转义可以是‘’‘’或者char(39)

如果使用静态sql(确保table存在,否则编译不过去),直接写sheetId,运行时会自动加上冒号

例如:

c.issuer_skdm_range_info_sheet=sheetId

2:

join_sql :='select count(distinct(m.equip_id)) from v_certificate_theater m,temp_theater theater,T_ISSUER_CINEMA c where c.cienma=m.cinema_id  and c.issuer_skdm_range_info_sheet='||''''||sheetId||''''||' and  m.is_jpeg=1 and m.is_mpeg=1 and m.theater_id=theater.theaterId and m.equip_id in (select equip_id from t_equip where equip_version_id in (select version_id from t_equip_version where equip_type in (select equiptypeid from t_skdmsheet_equiptype where skdmsheetid='||''''|| sheetId||''''||')))'
execute immediate join_sql into equipIdCount;

动态查询sql不要在拼接字符串的时候into,否则无法得到结果,现在还不知道为什么,有知道的可以分享一下。

静态sql:

select count(distinct(m.equip_id)) into con from v_certificate_theater

3:为了防止抛出没有查到数据(nodata)这样的错误,可以在使用select count(*) into con from table if con>0 then end if;来判断

4:存储过程里任何一个逻辑分支里面不允许出现没有语句的情况:

例如:

if con>0 then end if;--这样写编译不通过
if con>0 then null;
end if;--正确

5:

create or replace
PROCEDURE p_saveIssuerCinemaAdd_param(sheetId IN varchar2,issuerCinemaAddIds IN clob)

参数类型不用指明大小,as后面的声明里面需要指明大小
6:游标使用的例子:

create or replace
PROCEDURE saveSheetCinemaTheaters_old(sheetId IN varchar2,typeNum IN number)  Authid Current_User AS
--sheetId 任务id  typeNum 范围保存类型 1 地区 2 影院  3上传列表dETCC_Sql varchar2(4000) := 'drop table temp_ETCC';
dquipId_sql varchar2(4000) := 'drop table temp_quipId';
dfilmType_sql varchar2(4000) := 'drop table temp_filmType';
dtheaterId_sql varchar2(4000) := 'drop table temp_theaterId';
join_sql varchar2(4000);
CURSOR cur is--查询范围sheet信息select * from t_issuer_skdm_range_info_sheet t where t.sheet_id =sheetId;v cur%ROWTYPE;
BEGINETCC_sql :='create global temporary table temp_ETCC(id varchar2(32),certificateId varchar2(32),IS_JPEG number(1),IS_MPEG number(1),equipId varchar2(32),theaterId varchar2(32),cinemaId varchar2(32)) on commit preserve  ROWS';quipId_sql :='create global temporary table temp_quipId(id varchar2(32),equipId varchar2(32)) on commit preserve  ROWS';filmType_sql :='create global temporary table temp_filmType(id varchar2(32),IS_JPEG number(1),IS_MPEG number(1)) on commit preserve  ROWS';theaterId_sql :='create global temporary table temp_theaterId(id varchar2(32),theaterId varchar2(32)) on commit preserve  ROWS';--过滤影片类型select count(*) into con from t_skdmsheet_filmtype where skdmsheetid=sheetId;if(con>0) thenselect filmtypeid bulk collect into str_filmType from t_skdmsheet_filmtype where skdmsheetid=sheetId;for y in 1..con loopif(str_filmType(con)='MPEG2') thenis_mpeg :=1;end if;if(str_filmType(con)='JPEG2000') thenis_jpeg :=1;end if; if(str_filmType(con)='IMAX') thenis_jpeg :=1;end if;end loop;end if;--过滤影厅IDOPEN cur;LOOPBEGINfetch cur into v;exit when cur%notfound;--影厅idsstr_split :=fn_split( v.equip_info,',');dbms_output.put_line('str_split.count影厅个数'||str_split.count);if(str_split.count >0) thenfor y in 1..str_split.count loopjoin_sql := 'insert into temp_theaterId(id,theaterId) select sys_guid(),theater_id from t_theater where theater_id='||''''|| str_split(y).strValue||''''||' and theater_attribute in (select filmattribute from t_skdmsheet_attribute where skdmsheetid='||''''||sheetId||''''||')';dbms_output.put_line('theaterId_sql'||join_sql);execute immediate join_sql;-- insert into temp_theaterId(id,theaterId) --select sys_guid(),theater_id from t_theater -- where theater_id=str_split(y).strValue and theater_attribute in --(select filmattribute from t_skdmsheet_attribute where skdmsheetid=sheetId);end loop;end if;exception when others thenl_str:=sqlerrm(sqlcode);dbms_output.put_line(l_str);end;END LOOP;CLOSE cur;exception when others thenl_str:=sqlerrm(sqlcode);dbms_output.put_line(l_str);
end saveSheetCinemaTheaters_old;

7:

 select filmtypeid bulk collect into str_filmType from t_skdmsheet_filmtype where skdmsheetid=sheetId;
bulk collect

将查询出来的字段放入数组中

8:临时表杂谈

说到临时表,顺便提一下静态sql跟动态sql的区别,以及oracle的临时表创建与使用不同于其他厂商的数据库

(1):动态sql与静态sql

首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程。
在某种高级语言中,如果嵌入了SQL语句,而这个SQL语句的主体结构已经明确,例如在Java的一段代码中有一个待执行的SQL“select * from t1 where c1>5”,在Java编译阶段,就可以将这段SQL交给数据库管理系统去分析,数据库软件可以对这段SQL进行语法解析,生成数据库方面的可执行代码,这样的SQL称为静态SQL,即在编译阶段就可以确定数据库要做什么事情。
而如果嵌入的SQL没有明确给出,如在Java中定义了一个字符串类型的变量sql:String sql;,然后采用preparedStatement对象的execute方法去执行这个sql,该sql的值可能等于从文本框中读取的一个SQL或者从键盘输入的SQL,但具体是什么,在编译时无法确定,只有等到程序运行起来,在执行的过程中才能确定,这种SQL叫做动态SQL。例如每一种数据库软件都有能够执行SQL语句的界面,那个界面接收的SQL就是动态SQL,因为数据库厂商在做这个界面时,并不知道用户会输入哪些SQL,只有在该界面执行后,接收了用户的实际输入,才知道SQL是什么。
另外还要注意一点,在SQL中如果某些参数没有确定,如"select * from t1 where c1>? and c2<?",这种语句是静态SQL,不是动态SQL,虽然个别参数的值不知道,但整个SQL的结构已经确定,数据库是可以将它编译的,在执行阶段只需将个别参数的值补充进来即可。

(2)oracle中

execute immediate

其他数据库写法有可能不一样,意思一样

<pre id="best-content-809948816" class="best-text mb-10">简单来说 就是你一个存储过程当中 创建了一个表 table_a 然后要用insert into将其他的数据插入到这个table_a当中,但是因为你在创建过程的时候 table_a还不存在,过程就会显示有编译错误,因为table_a不存在必然导致过程无法执行,所以无法编译成功,而把insert into语句加如到 execute immediate之后 则oracle不会再去理会这个对象是否存在,因此可以成功编译和执行

(3):临时表

有一个问题重点说明,很简单但很容易忽略:如果你存储过程中使用到多个临时表,而且是事务级别的临时表,一定要在存储过程结束时再提交,不要在中途结束一个事务(切记:DDL操作自动提交事务,所以最好刚开始将所有用到的临时表一次性建好,防止中途建立另一张时隐性commit,把前面临时表的数据删除)。

<p style="background:rgb(255,252,246);">原表和临时表的共享操作不一样。一般来说,临时表只有你一个线程在用,没有任何用户、线程和你竞争使用该临时表。而原表总是有不同的用户、不同的线程在共享使用,对查询响最大的是有大量的数据在写入或者频繁的写入,那么查询的时候就会涉及到很多事务机制(并发、锁)的问题,产生了不同类型的等待事件,所以慢。相比较临时表就没有并发,只要服务器配置好,就非常快。</p><p style="background:rgb(255,252,246);"><span style="background:rgb(255,252,246);">虽然插入语句好像也包含了查询,可是其并不将查询结果返回,只是在数据库中直接打包做了复制而已,所以查询结果集越大,耗时差异越明显。</span></p><p style="background:rgb(255,252,246);">两个数据库临时表实现方式的异同:
<span style="font-family:Times New Roman;">SQL SERVER</span><span style="font-family:宋体;">临时表跟</span><span style="font-family:Times New Roman;">ORACLE</span><span style="font-family:宋体;">数据库临时表的差异,可以利用一句话来概括。</span><span style="font-family:Times New Roman;">SQL SERVER </span><span style="font-family:宋体;">临时表是在需要用到的时候创建</span><span style="font-family:Times New Roman;">; </span><span style="font-family:宋体;">而</span><span style="font-family:Times New Roman;">ORACLE </span><span style="font-family:宋体;">数据库的临时表,则是在数据库初始化中就开始创建,在具体的会话或者事务开始后进行操作,结束一个会话或者结束一个事务后该数据库的内容就会被清空。具体情况要看你建的是会话级别的临时表还是事务级别的临时表</span></p><p style="background:rgb(255,252,246);"><span style="color:#ff00;"></span><pre name="code" class="html">create global temporary table temp_cinema(id varchar2(32),cinemaId varchar2(32)) on commit delete ROWS --事务级别临时表,<span style="color:#ff00;">结束一个事务delete到所有数据</span>

在创建时的异同。

  SQL SERVER 数据库的临时表,是在实际需要时创建的。具体的来说,可以利用SELECT语句与CREAT语句创建临时表。如可以利用SELECT * INTO #USER_TEMP FROM USER; 通过这条语句就可以在需要的时间创建一张临时表。除此之外,还可以利用CREATE语句,在需要的时候创建临时表。

  而ORACLE数据库,是在数据库系统初始化的过程中,就需要建立临时表。也就是在用户安装财务管理软件系统时,初始化数据库系统时,系统就会创建临时表。而不是在临时表需要用到的时候,才被创建。故,ORACLE数据库的临时表创建方式只有一种,在数据库初始化的时候,利用CREATE创建数据库临时表。所以,ORACLE数据库临时表,又有另一种说法。我们一般称ORACLE数据库的临时表是永久性的,只是临时表的内容是临时的,在需要用到临时表时,只要直接调用即可,而不用临时创建。这不像SQL SERVER数据库那样,只有在用到时,才创建该临时表; 当结束会话时,不仅表中的数据被清空了,而且该表也被删除了。

SQL SERVER在结束一个会话后,就会把用户所创建的临时表删除。而ORACLE在结束一个会话或者一个事务时,删除的只是表的内容,表的结构仍然会存在。ORACLE就是凭借牺牲一点表结构的存储空间,来达到提高ORACLE 数据库临时表处理性能的目的。

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

 SQL SERVER数据库系统有两种临时表,一种是本地临时表,一种是全局临时表。本地临时表只在当前会话中可以查找到。也就是说,某个用户创建了一个临时表,只有本人可以查询得到,而其他用户是查询不到这张临时表的。第二种是全局临时表,这张表无论是谁创建的,只要该表的会话没有结束,即该临时表只要存在与数据库中,则任何登陆该数据库的用户都可以查询到该临时表的内容。无论是采取哪种表,只要创建该临时表的用户结束该对话时,则该表就会被自动删除。如要实现上面所讲的用户帐户重复登陆的问题,需要用到全局临时表。当一个系统用户登陆时,就新建一张以该用户名命名的临时表; 当另外一个用户也试图想以这个用户名登陆时,系统就会查到以该用户名为名字的临时表已经存在,如此,就会拒绝该用户名的再次登陆。而当该用户退出时,或者意外中断该会话时,则该临时表就会被系统删除。该帐户名下次登陆时,就可以正常使用。

  ORACLE数据库系统的临时表也有两种,一种是事务型临时表,一种是会话型临时表。事物型临时表是当一个事物结束时清空临时表的内容; 而会话型临时表就当一个会话中断或者被重新连接时数据表的内容就会清空了。从中,我们可以看到在数据清空方面,两个数据库处理方式的两个重大区别。一是ORACLE 数据库在清除临时表是,只清楚数据,而不清楚临时表的本身。二是从功能上来讲,ORACLE还提供了一种更加细分的事务型临时表。一个会话中,可能有多个事务。也就是说,ORACLE 清空临时型数据表的时间更加细腻,可以根据同一个会话中的不同事务来清空临时表。

  另外还要说明的一点就是,ORACLE的会话型临时中的内容对于各个用户来说,内容都是独立的。具体的说,就是各个用户在会话的过程中,都可以往一张临时表中存储数据; 但是用户查询临时表中的数据的时候,只能够查询到自己所创建的内容,而不能看到其他用户所增加的记录。这对于临时表的安全性来说,是非常有保障的。
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

三种主流数据库中临时表的使用

2011-03-31 22:04:35|  分类: 数据库知识 |  标签:|字号大中小 订阅

MS SQLSERVER
SQL Server 支持临时表。临时表就是那些名称以井号 (#) 开头的表。如果当用户断开连接时没有除去临时表,SQL Server 将自动除去临时表。临时表不存储在当前数据库内,而是存储在系统数据库 tempdb 内。
临时表有两种类型: 
本地临时表:本地临时表的名称以单个数字符号 (#) 打头;它们仅对当前的用户连接是可见的;当用户从 Microsoft SQL Server 2000 实例断开连接时被删除。
全局临时表:全局临时表的名称以数学符号 (##) 打头,创建后对任何用户都是可见的。如果在创建全局临时表的连接断开前没有显式地除去这些表,那么只要所有其它任务停止引用它们,这些表即被除去。当创建全局临时表的连接断开后,新的任务不能再引用它们。当前的语句一执行完,任务与表之间的关联即被除去;因此通常情况下,只要创建全局临时表的连接断开,全局临时表即被除去。
例如,如果创建名为 employees 的表,则任何人只要在数据库中有使用该表的安全权限就可以使用该表,除非它已删除。如果创建名为 #employees 的本地临时表,只有您能对该表执行操作且在断开连接时该表删除。如果创建名为 ##employees 的全局临时表,数据表中的任何用户均可对该表执行操作。如果该表在您创建后没有其他用户使用,则当您断开连接时该表删除。如果该表在您创建后有其他用户使用,则 SQL Server在所有用户断开连接后删除该表。
现在,临时表的许多传统用途可由具有 table 数据类型的变量替换。

ORACLE
Oracle支持临时表。临时表用来保存事务或会话期间的中间结果。在临时表中保存的数据只有对当前会话是可见的,任何会话都不能看到其他会话的数据,即使在当前会话COMMIT数据以后也是不可见的。多用户并行不是问题,一个会话从来不阻塞另一个会话使用临时表。即使锁定临时表,一个会话也不会阻塞其他会话使用临时表。临时表比正常表产生的REDO少得多,然而,由于临时表必须产生包含数据的UNDO信息,所以会产生一定数量的REDO日志。
临时表将从用户临时表空间的的目前日志中分配空间,或者如果从有定义权的程序中访问,将使用程序所有者的临时表空间。全局临时表实际上只是表本身的模板。创建临时表的行为不包括存储空间的分配,也不包括INITIAL的分配。因此,在运行时当一个会话首先将数据放到临时表中时,这时将创建这个会话的临时段。由于每个会话获取自己的临时段,每个用户可能在不同的表空间中为临时表分配空间。USER1的default临时表空间为TEMP1,他的临时表将从TEMP1中分配空间,USER2的default临时表空间为TEMP2,他的临时表将从TEMP2中分配空间。
临时表在每个数据库中只需创建一次,不必在每个存储过程中创建。临时表总是存在的,除非手动的删除他。临时表作为对象存在数据字典中,并且总是保持为空,直到有会话在其中放入数据。Oracle允许创建基于临时表的视图和存储过程。
临时表可以是以会话为基础的,也可以是以事务为基础的。ON COMMIT PRESERVE ROWS子句使临时表成为基于会话的模式。行将留在此表中,直到会话断开或通过DELETE或TRUNCATE从物理上删除这些行。ON COMMIT DELETE ROWS子句使临时表成为基于事务的模式。当会话提交后,行消失。这个临时表的自动清除过程不会有额外的开销。
在oracle中,应用程序需要的临时表应该在程序安装时创建,而不是在程序运行时创建。(这是与ms sqlserver或sybase的使用的不同)
在任何数据库中,临时表的一个缺点是:事实上优化器在临时表中没有真正的统计功能。然而,在oracle中,一系列较好的统计猜测可以通过DBMS_STATS包在临时表中设置。

oracle 存储过程的一些血与泪的教训相关推荐

  1. MongoDB--Linux下搭建的副本集集群(踩过的坑,血和泪的教训)

    MongoDB–Linux下搭建的副本集集群(踩过的坑,血和泪的教训) 文章目录 MongoDB--Linux下搭建的副本集集群(踩过的坑,血和泪的教训) 一:环境准备 二:安装步骤 三:启动 1.关 ...

  2. 目标检测--RFBNet环境配置、训练及验证 (血和泪的教训)

    最近接到任务,需要对目标检测进行一下调研.于是我面向GitHub进行了一波编程.经过一番比较发现,RFBNet貌似是非常不错的选择.所以就打算和跟我一样的新手们分享一下经验,也算是记录一下踩过的坑.哪 ...

  3. 血与泪的教训: JavaWeb中文乱码问题整合

    中文的字符编码集有:GB2312,GB18030,UTF-8(适用于中文,但偶尔会出错,前面两个比较有保障) Html页面乱码问题 在<head>标签中设置<meta charset ...

  4. 为什么不要去小公司上班?这是我血与泪的教训!!!

    工作是在大公司更好,还是小公司更好?这个问题让大家争论不休,也没有最终的答案.凑个热闹,我结合自己的经历,谈谈我的看法. 这个问题是比较有发言权的,博主小羊同学总共不到四年工作经验,大概也就是大公司和 ...

  5. Android Studio连接mysql8.0.25经验贴(三天血与泪的教训)

    使用mysql-connector-java8.0.25连接失败,解决方案:下载低版本的jar包!! 目录 使用mysql-connector-java8.0.25连接失败,解决方案:下载低版本的ja ...

  6. 一个90后创业者血与泪的教训

    我是一名90后,现在是一家移动互联网创业公司里的一名员工.如果回到2013年的这个时候我的名片上印着是"为你爱"创始人兼CEO.现在的我却背负了一身债务,每月为了还债整夜辗转反侧. ...

  7. SA-SSD环境搭建——血与泪的教训

    0 说在前面 SA-SSD论文:https://www4.comp.polyu.edu.hk/~cslzhang/paper/SA-SSD.pdf SA-SSD源码(pytorch):https:// ...

  8. 关于JavaScript,这10条血与泪的建议大家一定要看

    (注:本文翻译自国外著名杂志Noteworthy,文章在Medium编程类目冲上了一周热榜的榜首,本文版权归原作者The Cat with a Dragon Tattoo所有) 使用JavaScrip ...

  9. 我用血和泪的教训,再次告诉你:不要接私活

    loonggg 读完需要 3 分钟 速读仅需 1 分钟 大家好,我是你们的校长. 今天给大家讲一讲我最近的一个近况,真的是说可以是用血和泪来验证轻易不要再接私活了. 我之前在公众号写过很多关于不要接私 ...

最新文章

  1. Ascend Pytorch算子功能验证
  2. Spring boot 实战 利用 Sharding-jdbc实现数据库的读写分离
  3. No Module Named '_pywrap_tensorflow_internal'
  4. ubuntu 升级python3.8_Ubuntu上python升级到最新3.8版
  5. Java学习日报—Swagger介绍 与 布隆过滤器详解—2021/12/01
  6. cc1 transform链
  7. 安卓使用html文件遍历,安卓手机中使用html的input file,获取不到文件类型和文件名...
  8. 如何macOS 上优雅的使用 Gaussian 09 与GaussView 6
  9. EDA第一次课<1117电路图的绘制>
  10. 新版UNITY游戏(IL2CPP类型)使用内嵌型机器翻译插件XUnity.AutoTranslator的食用方法
  11. 手淘首页流量突然暴跌的原因,怎么办?
  12. CSS实现优惠券特殊样式的技巧
  13. 操作系统知识点总结(十四)文件保护:文件访问类型和访问控制
  14. c语言中row是什么意思中文,row是什么意思
  15. RedHat上安装openssl
  16. Golang面向对象之-类
  17. MacBook Pro win7系统下使用 苹果鼠标 apple mouse
  18. 动态规划-骨头收集者(一维数组,二维数组)
  19. 将扣出的章加入wps里面
  20. ##模拟图灵机 XN*2的运算

热门文章

  1. 十进制转二进制和十六进制 条件码标志和乘法指令
  2. 知乎音乐封神榜,你想听的都在这里。
  3. win10计算机管理字体糊,win10字体模糊如何解决
  4. 我的HTML基础学习笔记(复习)
  5. 朴淳 思庵 欲掩其跡
  6. 可扩展性对英特尔®至强处理器意味着什么
  7. 个人中心--订单业务流程
  8. Java节流阀设计与实现
  9. 历史大讲堂:这是真·图形化 苹果系统历史回顾(上)
  10. DirectX教程(1):基本Windows入门