Oracle基本命令
1 连接数据库: 2 使用sql*plus连接oracle 3 命令方式 4 1.conn[ect] 5 6 用法:conn 用户名/密码@网络服务名[as sysdba/sysoper]当用特权用户身份连接时,必须带上as sysdba或是as sysoper 7 8 远程连接:sqlplus usr/pwd@//host:port/sid 如:conn sys/admin@127.0.0.1:1521/orcl as sysdba; 9 10 2.disc[onnect] 11 12 说明: 该命令用来断开与当前数据库的连接 13 14 3.psssw[ord] 15 16 说明: 该命令用于修改用户的密码,如果要想修改其它用户的密码,需要用sys/system登录。4.show user 17 18 说明: 显示当前用户名 19 20 5.exit 21 22 说明: 该命令会断开与数据库的连接,同时会退出sql*plus 23 24 文件操作命令 25 1.start和@ 26 27 说明: 运行sql脚本 28 29 案例: sql>@ d:\a.sql或是sql>start d:\a.sql 30 31 2.edit 32 33 说明: 该命令可以编辑指定的sql脚本 34 35 案例: sql>edit d:\a.sql,这样会把d:\a.sql这个文件打开 36 37 3.spool 38 39 说明: 该命令可以将sql*plus屏幕上的内容输出到指定文件中去。 40 41 案例: sql>spool d:\b.sql 并输入 sql>spool off 42 43 显示和设置环境变量 44 概述:可以用来控制输出的各种格式,show all可以显示当前相关的设置 45 46 1.linesize 47 48 说明:设置显示行的宽度,默认是80个字符 49 50 show linesize 51 52 set linesize 90 53 54 查看当前所有表: 55 56 select * from tab; 57 58 查询当前日期 59 select to_char(sysdate,'yyyy-mm-dd,hh24:mi:ss') from dual; 60 61 查看本用户下的各种对象的SQL脚本 62 SQL语句: 63 64 表: 65 66 select * from cat; 67 68 select * from tab; 69 70 select table_name from user_tables; 71 72 视图: 73 74 select text from user_views where view_name=upper('&view_name'); 75 76 索引: 77 78 select index_name,table_owner,table_name,tablespace_name,status from user_indexes order by table_name; 79 80 触发器: 81 82 select trigger_name,trigger_type,table_owner,table_name,status from user_triggers; 83 84 快照: 85 86 select owner,name,master,table_name,last_refresh,next from user_snapshots order by owner,next; 87 88 同义词: 89 90 select * from syn; 91 92 序列: 93 94 select * from seq; 95 96 数据库链路: 97 98 select * from user_db_links; 99 100 约束限制: 101 102 select TABLE_NAME,CONSTRAINT_NAME,SEARCH_CONDITION,STATUS from user_constraints; 103 104 本用户读取其他用户对象的权限: 105 106 select * from user_tab_privs; 107 108 本用户所拥有的系统权限: 109 110 select * from user_sys_privs; 111 112 用户: 113 114 select * from all_users order by user_id; 115 116 表空间剩余自由空间情况: 117 118 select tablespace_name,sum(bytes) 总字节数,max(bytes),count(*) from dba_free_space group by tablespace_name; 119 120 数据字典: 121 122 select table_name from dict order by table_name; 123 124 锁及资源信息: 125 126 select * from v$lock;不包括DDL锁 127 128 数据库字符集: 129 130 select name,value$ from props$ where name='NLS_CHARACTERSET'; 131 132 inin.ora参数: 133 134 select name,value from v$parameter order by name; 135 136 SQL共享池: 137 138 select sql_text from v$sqlarea; 139 140 数据库: 141 142 select * from v$database 143 144 控制文件: 145 146 select * from V$controlfile; 147 148 重做日志文件信息: 149 150 select * from V$logfile; 151 152 来自控制文件中的日志文件信息: 153 154 select * from V$log; 155 156 来自控制文件中的数据文件信息: 157 158 select * from V$datafile; 159 160 NLS参数当前值: 161 162 select * from V$nls_parameters; 163 164 ORACLE版本信息: 165 166 select * from v$version; 167 168 描述后台进程: 169 170 select * from v$bgprocess; 171 172 查看版本信息: 173 174 select * from product_component_version; 175 176 表空间管理 177 概述: 178 Oracle表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才能创建用户对象。否则是不充许创建对象,因为就是想创建对象,如表,索引等,也没有地方存放,Oracle会提示:没有存储配额。因此,在创建对象之前,首先要分配存储空间。分配存储,就要创建表空间 179 180 Oracle可以创建的表空间有三种类型: 181 182 (1)TEMPORARY: 临时表空间,用于临时数据的存放;创建临时表空间的语法如下:CREATE TEMPORARY TABLESPACE "SAMPLE"。。。。。。 183 184 (2)UNDO : 还原表空间。用于存入重做日志文件。创建还原表空间的语法如下:CREATE UNDOTABLESPACE "SAMPLE"。。。。。。 185 186 (3)用户表空间: 最重要,也是用于存放用户数据表空间可以直接写成: CREATE TABLESPACE"SAMPLE"TEMPORARY 和 UNDO 表空间是Oracle 管理的特殊的表空间。只用于存放系统相关数据。 187 188 查看表空间的名字和所属文件 189 select tablespace_name, file_id, file_name, 190 191 round(bytes/(1024*1024),0) total_space 192 193 from dba_data_files 194 195 order by tablespace_name; 196 197 创建表空间: 198 创建表空间名称为:epet_tablespace 199 200 表空间的物理文件位置:E:\oracle\product\10.2.0\oradata\JBITDB\EPET.DBF 大小为100M 201 202 CREATE TABLESPACE epet_tablespace 203 204 DATAFILE 'E:\oracle\product\10.2.0\oradata\JBITDB\EPET.DBF' 205 206 SIZE 100M; 207 208 修改表空间并为表空间添加物理文件: 209 ALTER TABLESPACE JIANGWFTABLESPACE ADD DATAFILE 'E:\PROJECTS\ZHONGHUA\PROJECT\DATABASE\ZHONGHUA\JIANGWFTABLESPACE2.DBF' 210 211 size 50m; 212 213 214 215 ALTER TABLESPACE "TEMPTABLESPACE" ADD DATAFILE 'E:\PROJECTS\ZHONGHUA\PROJECT\DATABASE\ZHONGHUA\JIANGWFTABLESPACE2.ORA' 216 217 SIZE 5M AUTOEXTEND ON NEXT 100K MAXSIZE UNLIMITED 218 219 增加表空间大小的四种方法 220 Meathod1:给表空间增加数据文件 221 222 ALTER TABLESPACE app_data ADD DATAFILE 223 224 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF' SIZE 50M; 225 226 227 228 Meathod2:新增数据文件,并且允许数据文件自动增长 229 230 ALTER TABLESPACE app_data ADD DATAFILE 231 232 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP04.DBF' SIZE 50M 233 234 AUTOEXTEND ON NEXT 5M MAXSIZE 100M; 235 236 237 238 Meathod3:允许已存在的数据文件自动增长 239 240 ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP03.DBF' 241 242 AUTOEXTEND ON NEXT 5M MAXSIZE 100M; 243 244 245 246 Meathod4:手工改变已存在数据文件的大小 247 248 ALTER DATABASE DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\EDWTEST\APP02.DBF' 249 250 RESIZE 100M; 251 252 253 254 修改物理文件大小 255 alter database datafile 'E:\PROJECTS\ZHONGHUA\PROJECT\DATABASE\ZHONGHUA\JIANGWFTABLESPACE3.DBF' 256 257 resize 10M 258 259 修改用户表table的表空间 260 alter table 表名 move tablespace 新表空间名; 261 262 查询所有用户表: 263 select * from user_tables; 264 265 删除表空间: 266 drop tablespace 表空间名称 267 268 269 270 移动表至另一表空间 271 alter table move tablespace room1; 272 273 建立临时表空间 274 CREATE TEMPORARY TABLESPACE temp_data 275 276 TEMPFILE '/oracle/oradata/db/TEMP_DATA.dbf' SIZE 50M 277 278 设定后查看表空间信息 279 SELECT A.TABLESPACE_NAME,A.BYTES TOTAL,B.BYTES USED, C.BYTES FREE, 280 281 (B.BYTES*100)/A.BYTES "% USED",(C.BYTES*100)/A.BYTES "% FREE" 282 283 FROM SYS.SM$TS_AVAIL A,SYS.SM$TS_USED B,SYS.SM$TS_FREE C 284 285 WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME AND A.TABLESPACE_NAME=C.TABLESPACE_NAME; 286 287 用户管理: 288 创建用户 289 概述:在oracle中要创建一个新的用户使用create user语句,一般是具有dba(数据库管理员)的权限才能使用。 290 291 语法格式:create user 用户名 identified by 密码; 292 293 创建用户 294 create user EPET 295 296 identified by "BDQN" 297 298 default tablespace "EPET_TABLESPACE" 299 300 temporary tablespace "DIAOCHA_TEMP" 301 302 profile DEFAULT 303 304 ACCOUNT UNLOCK; 305 306 给用户赋予某个角色的权限: 307 308 grant 角色 to QIUDING; 309 310 grant unlimited tablespace to QIUDING 311 312 查看当前用户所属角色: 313 select * from user_role_privs; 314 315 查看当前用户的缺省表空间 316 select username,default_tablespace from user_users; 317 318 查看某用户所拥有的对象: 319 SELECT owner,object_name, object_type FROM dba_objects WHERE owner= 'EPET'; 320 321 查看某用户的所有表: 322 select * from all_tables where owner='SHOPXP';--用户名称为“SHOPXP”的所有表 323 324 给用户修改密码 325 概述:如果给自己修改密码可以直接使用 326 327 password 用户名 328 329 如果给别人修改密码则需要具有dba的权限,或是拥有alter user的系统权限 330 331 alter user 用户名 identified by 新密码 332 333 删除用户 334 概述:一般以dba的身份去删除某个用户,如果用其它用户去删除用户则需要具有drop user的权限。 335 336 比如 drop user 用户名 【cascade】 337 338 在删除用户时,注意: 339 340 如果要删除的用户,已经创建了表,那么就需要在删除的时候带一个参数cascade; 341 342 343 344 权限说明: 345 346 创建的新用户是没有任何权限的,甚至连登陆的数据库的权限都没有,需要为其指定相应的权限。给一个用户赋权限使用命令grant,回收权限使用命令revoke。 347 348 349 350 角色管理 351 1.connect角色 352 connect角色具有一般应用开发人员需要的大部分权限,当建立了一个用户后,多数情况下,只要给用户授予connect和 resource角色就够了,那么connect角色具有哪些系统权限呢? 353 354 alter session 355 356 create table 357 358 create view 359 360 create sequence create cluster 361 362 create database link 363 364 create session 365 366 2.resource角色 367 resource角色具有应用开发人员所需要的其它权限,比如建立存储过程,触发器等。这里需要注意的是 resource角色隐含了unlimited tablespace系统权限。 368 369 resource角色包含以下系统权限: 370 371 create cluster 372 373 create indextype 374 375 create table 376 377 create sequence create type 378 379 create procedure 380 381 create trigger 382 383 3.dba角色 384 dba角色具有所有的系统权限,及with admin option选项,默认的dba用户为sys和system,它们可以将任何系统权限授予其他用户。但是要注意的是dba角色不具备sysdba和sysoper的特权(启动和关闭数据库)。 385 386 自定义角色. 387 388 顾名思义就是自己定义的角色,根据自己的需要来定义。一般是dba来建立,如果用别的用户来建立,则需要具有create role的系统权限。在建立角色时可以指定验证方式(不验证,数据库验证等)。 389 390 4:创建角色: 391 CREATE ROLE "QIUDINGROLE" NOT IDENTIFIED; 392 393 把角色赋予某个用户 394 395 GRANT "CONNECT" TO "QIUDINGROLE"; 396 397 GRANT "DBA" TO "QIUDINGROLE"; 398 399 GRANT "RESOURCE" TO "QIUDINGROLE"; 400 401 5:给角色授权: 402 grant select on scott.emp to 角色名; 403 404 grant insert, update, delete on scott.emp to 角色名; 405 406 6:把某个角色的权限赋予某个用户 407 grant 角色名 to 用户名称 408 409 GRANT DBA TO用户名称; 410 411 GRANT resource TO用户名称; 412 413 7:显示所有角色 414 SQL> select * from dba_roles; 415 416 Oracle表的管理 417 表名和列的命名规则 418 · 必须以字母开头 419 420 · 长度不能超过30个字符 421 422 · 不能使用oracle的保留字 423 424 · 只能使用如下字符 A-Z,a-z,0-9,$,#等 425 426 oracle支持的数据类型 427 字符类 428 char 定长 最大2000个字符。 429 430 例子:char(10) ‘小韩’前四个字符放‘小韩’,后添6个空格补全 如‘小韩 ’ varchar2(20) 变长 最大4000个字符。 431 432 例子:varchar2(10) ‘小韩’ oracle分配四个字符。这样可以节省空间。 433 434 clob(character large object) 字符型大对象 最大4G 435 436 char 查询的速度极快浪费空间,查询比较多的数据用。 437 438 varchar 节省空间 439 440 数字型 441 number范围 -10的38次方 到 10的38次方,可以表示整数,也可以表示小数 :number(5,2)表示一位小数有5位有效数,2位小数 442 443 范围:-999.99到999.99 444 445 number(5) 表示一个5位整数 446 447 448 449 范围99999到-99999 450 451 452 453 日期类型 454 date 包含年月日和时分秒 oracle默认格式 1-1月-1999 455 456 timestamp 这是oracle9i对date数据类型的扩展。可以精确到毫秒。 457 458 日期类型相关函数和格式转换函数的使用 459 获取系统日期: SYSDATE() 460 461 格式化日期: TO_CHAR(SYSDATE(),'YY/MM/DD HH24:MI:SS) 462 463 或 TO_DATE(SYSDATE(),'YY/MM/DD HH24:MI:SS) 464 465 格式化数字: TO_NUMBER 466 467 注: TO_CHAR 把日期或数字转换为字符串 468 469 TO_CHAR(number, '格式') 470 471 TO_CHAR(salary, '$99,999.99') 472 473 TO_CHAR(date, '格式') 474 475 TO_DATE 把字符串转换为数据库中的日期类型 476 477 TO_DATE(char, '格式') 478 479 TO_NUMBER 将字符串转换为数字 480 481 TO_NUMBER(char, '格式') 482 483 返回系统日期,输出 25-12月-09 484 485 select sysdate from dual; 486 487 mi是分钟,输出 2009-12-25 14:23:31 488 489 select to_char(sysdate,'yyyy-MM-dd HH24:mi:ss') from dual; 490 491 mm会显示月份,输出 2009-12-25 14:12:31 492 493 select to_char(sysdate,'yyyy-MM-dd HH24:mm:ss') from dual; 494 495 输出 09-12-25 14:23:31 496 497 select to_char(sysdate,'yy-mm-dd hh24:mi:ss') from dual 498 499 输出 2009-12-25 14:23:31 500 501 select to_date('2009-12-25 14:23:31','yyyy-mm-dd,hh24:mi:ss') from dual 502 503 而如果把上式写作: 504 505 select to_date('2009-12-25 14:23:31','yyyy-mm-dd,hh:mi:ss') from dual 506 507 则会报错,因为小时hh是12进制,14为非法输入,不能匹配。 508 509 输出 $10,000,00 : 510 511 select to_char(1000000,'$99,999,99') from dual; 512 513 输出 RMB10,000,00 : 514 515 select to_char(1000000,'L99,999,99') from dual; 516 517 输出 1000000.12 : 518 519 select trunc(to_number('1000000.123'),2) from dual; 520 521 select to_number('1000000.123') from dual; 522 523 转换的格式: 524 525 表示 year 的:y 表示年的最后一位 、 526 527 yy 表示年的最后2位 、 528 529 yyy 表示年的最后3位 、 530 531 yyyy 用4位数表示年 532 533 表示month的: mm 用2位数字表示月 、 534 535 mon 用简写形式, 比如11月或者nov 、 536 537 month 用全称, 比如11月或者november 538 539 表示day的: dd 表示当月第几天 、 540 541 ddd 表示当年第几天 、 542 543 dy 当周第几天,简写, 比如星期五或者fri 、 544 545 day 当周第几天,全称, 比如星期五或者friday 546 547 表示hour的:hh 2位数表示小时 12进制 、 548 549 hh24 2位数表示小时 24小时 550 551 表示minute的:mi 2位数表示分钟 552 553 表示second的:ss 2位数表示秒 60进制 554 555 表示季度的:q 一位数 表示季度 (1-4) 556 557 另外还有ww 用来表示当年第几周 w用来表示当月第几周。 558 559 24小时制下的时间范围:00:00:00-23:59:59 560 561 12小时制下的时间范围:1:00:00-12:59:59 562 563 数字格式: 9 代表一个数字 564 565 0 强制显示0 566 567 $ 放置一个$符 568 569 L 放置一个浮动本地货币符 570 571 . 显示小数点 572 573 , 显示千位指示符 574 575 补充: 576 577 当前时间减去7分钟的时间 578 579 select sysdate,sysdate - interval '7' MINUTE from dual; 580 581 当前时间减去7小时的时间 582 583 select sysdate - interval '7' hour from dual; 584 585 当前时间减去7天的时间 586 587 select sysdate - interval '7' day from dual; 588 589 当前时间减去7月的时间 590 591 select sysdate,sysdate - interval '7' month from dual; 592 593 当前时间减去7年的时间 594 595 select sysdate,sysdate - interval '7' year from dual; 596 597 时间间隔乘以一个数字 598 599 select sysdate,sysdate - 8*interval '7' hour from dual; 600 601 图片 602 blob 二进制数据 可以存放图片/声音 4G 一般来讲,在真实项目中是不会把图片和声音真的往数据库里存放,一般存放图片、视频的路径,如果安全需要比较高的话,则放入数据库。 603 604 创建表的案例 605 --创建好了表空间和用户student后 606 607 --用student用户登录,就可以创建表了 608 609 create table grade 610 611 ( 612 613 gradeid number primary key, 614 615 name varchar2(29), 616 617 location varchar2(30) 618 619 ) 620 621 --create sequence seq_grade increment by 1 start with 1 nomaxvalue nocycle 622 623 --nocache; 624 625 --create or replace trigger tri_grade before insert on grade for each row 626 627 --begin 628 629 -- select seq_grade.Nextval into:new.gradeid from dual; 630 631 632 633 --end 634 635 insert into grade(gradeid,name,location) values(1,'jiangwf','shenzhen'); 636 637 insert into grade(gradeid,name,location) values(2,'zhulei','shenzhen'); 638 639 insert into grade(gradeid,name,location) values(3,'jianghaoyu','shenzhen'); 640 641 select * from grade 642 643 644 645 create table 学生表 646 647 ( 648 649 学生编号 number primary key, 650 651 学生姓名 varchar2(50), 652 653 学生地址 varchar2(50) 654 655 ); 656 657 658 659 insert into 学生表(学生编号,学生姓名,学生地址) values(1,'jiangwf','shenzhen'); 660 661 insert into 学生表(学生编号,学生姓名,学生地址) values(2,'zhulei','shenzhen'); 662 663 insert into 学生表(学生编号,学生姓名,学生地址) values(3,'jianghaoyu','shenzhen'); 664 665 建一个和a表结构一样的空表 666 create table b as select * from a where 1=2; 667 668 create table b(b1,b2,b3) as select a1,a2,a3 from a where 1=2; 669 670 创建序列(名称为:myCus_seq) 671 CREATE SEQUENCE myCus_seq 672 673 START WITH 1 674 675 INCREMENT BY 1 676 677 NOMAXVALUE 678 679 CACHE 10; 680 681 SQL编程语法: 682 循环的语句格式: 683 declare 684 685 x number; 686 687 begin 688 689 x:=0; 690 691 loop 692 693 x:=x+1; 694 695 if x>=3 then 696 697 exit; 698 699 end if; 700 701 dbms_output.put_line('内部x='||x); 702 703 end loop; 704 705 dbms_output.put_line('外部x='||x); 706 707 end; 708 709 / 710 711 ------------------------------------------------------------- 712 713 begin 714 715 for i in 1..5 loop 716 717 dbms_output.put_line('内部i='||i); 718 719 end loop; 720 721 dbms_output.put_line('结束'); 722 723 end; 724 725 / 726 727 --------------------------------------------------------------- 728 729 declare 730 731 x number; 732 733 begin 734 735 x:=0; 736 737 while x<=3 loop 738 739 x:=x+1; 740 741 dbms_output.put_line('内部x='||x); 742 743 end loop; 744 745 dbms_output.put_line('外部x='||x); 746 747 end; 748 749 / 750 751 自定义函数和使用 752 创建函数 753 Oracle创建函数(function) 754 1、基本语法规则如下: 755 756 create or replace function (Name in type, Name in type, ...) return number is 757 758 Result number; 759 760 begin 761 762 return (Result); 763 764 end ; 765 766 767 768 ----例子--------------------------------------------------------------------- 769 770 create or replace function getmastername(uid number) return varchar2 771 772 as 773 774 mname varchar2(50); 775 776 begin 777 778 select loginid into mname from master where master.id=uid; 779 780 return mname; 781 782 end; 783 784 案例1: 785 create or replace function jiangwf.getUserName(userid varchar2) 786 787 return varchar2 788 789 is 790 791 uName varchar2(50); 792 793 begin 794 795 select nvl(UserName,'') into uName from jiangwf.UserInfo where UserNo=userid; 796 797 return uName; 798 799 end; 800 801 802 803 调用函数 804 805 select jiangwf.getUserName(UserNo),jiangwf.UserInfo.UserPWD from jiangwf.UserInfo 806 807 ********************************************************************************************* 808 809 案例2: 810 创建函数 811 812 create or replace function jiangwf.getUserPWD(userid varchar2) 813 814 return varchar2 815 816 is 817 818 UserPassWord varchar2(50); 819 820 begin 821 822 select nvl(UserPWD,'') into UserPassWord from jiangwf.UserInfo where UserNo=userid; 823 824 return UserPassWord; 825 826 end; 827 828 调用: 829 830 select jiangwf.UserInfo.*,jiangwf.getUserPWD(UserNo) from jiangwf.UserInfo; 831 832 833 834 存储过程相关: 835 1、基本语法 836 create or replace procedure update_emp_sal 837 838 (Name in out type, 839 840 Name in out type, ... 841 842 ) is 843 844 begin 845 846 847 848 end update_emp_sal; 849 850 851 852 写一个简单的例子修改emp表的ename字段 853 create or replace procedure update_emp 854 855 ( 856 857 v_empno varchar2, 858 859 v_ename varchar2 860 861 ) is 862 863 begin 864 865 update emp set ename=v_ename where empno=v_empno; 866 867 end update_emp; 868 869 调用方法如下: 870 871 exec update_emp('7935','test'); 872 873 有返回值的存储过程 874 就写一个简单的返回empno=7935的sal值 875 876 create or replace procedure emp_out_sal 877 878 ( 879 880 v_empno in varchar2, 881 882 v_sal out number 883 884 ) is 885 886 vsal number(7,2); 887 888 begin 889 890 select sal into vsal from emp where empno=v_empno; 891 892 v_sal:=vsal; 893 894 end; 895 896 897 898 调用有返回值的过程 899 900 var vsal number 901 902 exec emp_out_sal('7935',:vsal); 903 904 PL/SQL procedure successfully completed 905 906 vsal 907 908 --------- 909 910 700 911 912 SQL> var vsal number 913 914 SQL> call emp_out_sal('7935',:vsal); 915 916 Method called 917 918 vsal 919 920 --------- 921 922 700 923 924 Oracle创建包 925 概述: 926 包用于组合逻辑相关的过程和函数,它由包规范和包体两个部分组成。包规范用于定义公用的常量、变量、过程和函数,创建包规范可以使用CREATE PACKAGE命令,创建包体可以使用CREATE PACKAGE BODY 927 928 1、创建包规范 929 create package emp_pkg is 930 931 procedure emp_update_ename(v_empno varchar2,v_ename varchar2); 932 933 function emp_get_sal(v_empno varchar2) return number; 934 935 end; 936 937 创建包体 938 939 create or replace package body emp_pkg 940 941 is 942 943 procedure emp_update_ename 944 945 ( 946 947 v_empno varchar2, 948 949 v_ename varchar2 950 951 ) 952 953 is 954 955 vename varchar2(32); 956 957 begin 958 959 update emp set ename=v_ename where empno=v_empno; 960 961 commit; 962 963 select ename into vename from emp where empno=v_empno; 964 965 966 967 dbms_output.put_line('雇员名称:'||vename); 968 969 970 971 end; 972 973 974 975 function emp_get_sal 976 977 ( 978 979 v_empno varchar2 980 981 ) 982 983 return number is 984 985 vsal number(7,2); 986 987 begin 988 989 select sal into vsal from emp where empno=v_empno; 990 991 return vsal; 992 993 end; 994 995 end; 996 997 在此提示,在没有创建包规范就创建包体,会失败,要使用包,必须先创建包规范,然后在创建包体 998 999 当要调用包的过程和函数时,在过程和函数的名称前加上包名作为前缀(包名.子程序名称),而如果要访问其他方案的包时需要在包的名称前加上方案的名称(方案名称.包名.子程序名称) 1000 1001 实例: 1002 SQL> var vsla number 1003 1004 SQL> call emp_pkg.emp_get_sal('7935') into :vsal; 1005 1006 Method called 1007 1008 vsal 1009 1010 --------- 1011 1012 700 1013 1014 SQL> exec emp_pkg.emp_update_ename('7935','helong'); 1015 1016 雇员名称:helong 1017 1018 SQL> call emp_pkg.emp_update_ename('7935','helong'); 1019 1020 Method called 1021 1022 SQL> select * from dual; 1023 1024 DUMMY 1025 1026 ----- 1027 1028 X 1029 1030 用pl/sql developer导出表结构和数据 1031 1、点击Tools--Export User Objects 1032 这种方式可以导出当前用户拥有的所有对象,包括表、视图、触发器、同义词等等,对于表,只能导出表结构,不能导出数据,选中要导出的对象,设置好导出的路径和各个参数后,点击Export就OK 1033 1034 PS:这种方式还可以导出其他用户的对象,在下面user下拉框中选择要用户就可以,默认是系统当前登录用户 1035 1036 2、如果想将表中数据一起导出,可用Tools--Export Tables: 1037 1038 这种方式导出的文件,本身就带着创建表结构的sql语句 选中要导出的表(可选多个),导出方式有三种: 1039 1040 Oracle Export,Sql Insert,pl/sql developer 1041 1042 第一种是导出为.dmp的文件: 1043 1044 .dmp文件是二进制的,可以跨平台,还能包含权限,效率也很不错,用得最广 1045 1046 第二种是导出为.sql文件: 1047 1048 可用文本编辑器查看,通用性比较好,但效率不如第一种,适合小数据量导入导出。尤其注意的是表中不能有大字段(blob,clob),如果有,会提示不能导出,可以用第一种和第三种方式导出。 1049 1050 第三种是导出为.pde格式: 1051 1052 .pde为Pl/sql developer自有的文件格式,只能用Pl/sql developer自己导入导出;不能用编辑器查看,效率不知道怎么样 1053 1054 PS:只有“Oracle Export”方式导出再导入后,表结构和索引结构没有发生变化,另两种方式都改变了索引类型。 导入的情况和导出一样
数据库权限管理
1 权限: 2 3 create session 允许用户登录数据库权限 4 5 create table 允许用户创建表权限 6 7 unlimited tablespace 允许用户在其他表空间随意建表 8 9 角色: 10 11 connect 12 13 resource 14 15 dba 16 17 18 19 CONNECT角色: --是授予最终用户的典型权利,最基本的权力,能够连接到ORACLE数据库中,并在对其他用户的表有访问权限时,做SELECT、UPDATE、INSERTT等操作。 20 ALTER SESSION --修改会话 21 CREATE CLUSTER --建立聚簇 22 CREATE DATABASE LINK --建立数据库链接 23 CREATE SEQUENCE --建立序列 24 CREATE SESSION --建立会话 25 CREATE SYNONYM --建立同义词 26 CREATE VIEW --建立视图 27 RESOURCE角色: --是授予开发人员的,能在自己的方案中创建表、序列、视图等。 28 CREATE CLUSTER --建立聚簇 29 CREATE PROCEDURE --建立过程 30 CREATE SEQUENCE --建立序列 31 CREATE TABLE --建表 32 CREATE TRIGGER --建立触发器 33 CREATE TYPE --建立类型 34 35 DBA角色,是授予系统管理员的,拥有该角色的用户就能成为系统管理员了,它拥有所有的系统权限 36 37 例: 38 39 #sqlplus /nolog 40 41 SQL> conn / as sysdba; 42 43 SQL>create user username identified by password --username/password都是用户自定义 44 45 SQL> grant dba to username; 46 47 SQL> conn username/password 48 49 SQL> select * from user_sys_privs; 50 51 我们将从创建Oracle用户权限表开始谈起,然后讲解登陆等一般性动作,使大家对Oracle用户权限表有个深入的了解。 52 53 一、创建 54 55 sys;//系统管理员,拥有最高权限 56 57 system;//本地管理员,次高权限 58 59 scott;//普通用户,密码默认为tiger,默认未解锁 60 61 oracle有三个默认的用户名和密码~ 62 1.用户名:sys密码:change_on_install 63 2.用户名:system密码:manager 64 3.用户名:scott密码:tiger 65 二、登陆 66 67 sqlplus / as sysdba;//登陆sys帐户 68 69 sqlplus sys as sysdba;//同上 70 71 sqlplus scott/tiger;//登陆普通用户scott 72 73 三、管理用户 74 75 create user zhangsan;//在管理员帐户下,创建用户zhangsan 76 77 alert user scott identified by tiger;//修改密码 78 79 四,授予权限 80 81 1、默认的普通用户scott默认未解锁,不能进行那个使用,新建的用户也没有任何权限,必须授予权限 82 83 84 85 grant create session to zhangsan;//授予zhangsan用户创建session的权限,即登陆权限,允许用户登录数据库 86 87 grant unlimited tablespace to zhangsan;//授予zhangsan用户使用表空间的权限 88 89 grant create table to zhangsan;//授予创建表的权限 90 91 grante drop table to zhangsan;//授予删除表的权限 92 93 grant insert table to zhangsan;//插入表的权限 94 95 grant update table to zhangsan;//修改表的权限 96 97 grant all to public;//这条比较重要,授予所有权限(all)给所有用户(public) 98 99 2、oralce对权限管理比较严谨,普通用户之间也是默认不能互相访问的,需要互相授权 100 101 102 103 grant select on tablename to zhangsan;//授予zhangsan用户查看指定表的权限 104 105 grant drop on tablename to zhangsan;//授予删除表的权限 106 107 grant insert on tablename to zhangsan;//授予插入的权限 108 109 grant update on tablename to zhangsan;//授予修改表的权限 110 111 grant insert(id) on tablename to zhangsan; 112 113 grant update(id) on tablename to zhangsan;//授予对指定表特定字段的插入和修改权限,注意,只能是insert和update 114 115 grant alert all table to zhangsan;//授予zhangsan用户alert任意表的权限 116 117 五、撤销权限 118 119 基本语法同grant,关键字为revoke 120 121 六、查看权限 122 123 select * from user_sys_privs;//查看当前用户所有权限 124 125 select * from user_tab_privs;//查看所用用户对表的权限 126 127 七、操作表的用户的表 128 129 130 131 select * from zhangsan.tablename 132 133 八、权限传递 134 135 即用户A将权限授予B,B可以将操作的权限再授予C,命令如下: 136 137 grant alert table on tablename to zhangsan with admin option;//关键字 with admin option 138 139 grant alert table on tablename to zhangsan with grant option;//关键字 with grant option效果和admin类似 140 141 九、角色 142 143 角色即权限的集合,可以把一个角色授予给用户 144 145 create role myrole;//创建角色 146 147 grant create session to myrole;//将创建session的权限授予myrole 148 149 grant myrole to zhangsan;//授予zhangsan用户myrole的角色 150 151 drop role myrole;删除角色
数据库的约束
1 约束: 2 用于确保数据库数据满足特定的商业规则。 3 Oracle中的约束包括: 4 not null: 5 unique: 6 primary key: pk 7 foreign key: fk 8 check: 9 10 a.not null : 非空约束: 11 如果在列上定义了not null,那么增加数据时,必须为该列提供数据。 12 13 b.unique : 唯一约束: 14 当定义唯一约束后,该列的值是不能重复的,但是可以为null。比如:身份证号、产品编号、... 15 16 c.primary key : 主键约束: 17 用于唯一的标示表行的数据。当定义了主键约束后,该列不但不能重复,而且不能为null。 18 注意:一张表最多只能由一个主键(可以有联合主键),但是可以有多个unique约束。 19 20 d.foreign key : 外键约束: 21 用于定义主表和从表之间的关系。外键约束要定义在从表上,主表则必须具有主键约束或者unique约束。 22 当定义外键约束后,要求外键列的数据必须在主表的主键列存在或是为null。 23 24 e.check : 检查约束: 25 用于强制列数据必须满足条件。 26 如:假如在sal列上定义了check约束,并要求sal列值在1000--2000之间,那么在增加数据时,工资少于1000或者大于2000,就会报check约束错误。
游标
1 一、涉及内容 2 3 游标的创建与应用 4 5 二、具体操作 6 7 (一)填空题 8 9 1.PL/SQL 程序块主要包含3个部分:声明部分、(执行部分 )、异常处理部分。 10 11 2.自定义异常必须使用(RAISE )语句引发。 12 13 (二)选择题 14 15 1.下列哪一个不是BOOLEAN变量可能的取值?(D ) 16 17 A.TRUE B.FALSE C.NULL D.BLANK 18 19 2.请查看以下IF语句: 20 21 复制代码 22 Declare 23 sal number:=500; 24 comm number; 25 Begin 26 If sal <100 then 27 Comm :=0; 28 Elsif sal <600 then 29 Comm: =sal*0.1; 30 Else sal <1000 then 31 Comm: =sal*0.15; 32 Else 33 Comm: =sal*0.2; 34 End if; 35 End; 36 复制代码 37 在执行了以上语句之后,变量comm 的结果应是:(B ) 38 39 A.0 B.50 C.75 D.100 40 41 3.在以下哪些语句中可以包含WHERE CURRENT OF 子句?(CE) 42 43 A.OPEN B.FETCH C.DELETE D.SELECT E.UPDATE F.CURSOR 44 45 4.在异常和oracle错误之间建立关联时,应该在哪个部分完成?(A) 46 47 A.定义部分 B.执行部分 C.异常处理部分 48 49 5.只能存在一个值的变量是哪种变量?(B ) 50 51 A.游标 B.标量变量 C.游标变量 D.记录变量 52 53 54 55 (三)编程题 56 57 1.编写程序计算并输出1~100的和。 58 59 方案一: 60 61 语句: 62 63 复制代码 64 Declare 65 v_sum integer:=0; 66 begin 67 for i in 1..100 loop 68 v_sum := v_sum+i; 69 end loop; 70 dbms_output.put_line(‘1~100的和为:’|| v_sum); 71 end; 72 / 73 复制代码 74 截图: 75 76 77 78 方案二: 79 80 语句: 81 82 复制代码 83 Declare 84 v_sum integer; 85 begin 86 v_sum := 100*101/2; 87 dbms_output.put_line(‘1~100的和为:’|| v_sum); 88 end; 89 / 90 复制代码 91 截图: 92 93
oracle异常处理
1 异常处理概念 2 3 异常情况处理(EXCEPTION)是用来处理正常执行过程中未预料的事件,程序块的异常处理预定义的错误和自定义错误,由于PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会自动终止整个程序运行. 4 5 6 7 有三种类型的异常错误: 8 9 1. 预定义 ( Predefined )错误 10 11 ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。 12 13 2. 非预定义 ( Predefined )错误 14 15 即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。 16 17 3. 用户定义(User_define) 错误 18 19 程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。 20 21 22 23 异常处理部分一般放在 PL/SQL 程序体的后半部,结构为: 24 25 26 27 28 29 EXCEPTION 30 WHEN first_exception THEN <code to handle first exception > 31 WHEN second_exception THEN <code to handle second exception > 32 WHEN OTHERS THEN <code to handle others exception > 33 END; 34 35 36 异常处理可以按任意次序排列,但 OTHERS 必须放在最后. 37 38 39 40 5.1.1 预定义的异常处理 41 42 43 预定义说明的部分 ORACLE 异常错误 44 45 错误号 46 47 异常错误信息名称 48 49 说明 50 51 ORA-0001 52 53 Dup_val_on_index 54 55 违反了唯一性限制 56 57 ORA-0051 58 59 Timeout-on-resource 60 61 在等待资源时发生超时 62 63 ORA-0061 64 65 Transaction-backed-out 66 67 由于发生死锁事务被撤消 68 69 ORA-1001 70 71 Invalid-CURSOR 72 73 试图使用一个无效的游标 74 75 ORA-1012 76 77 Not-logged-on 78 79 没有连接到ORACLE 80 81 ORA-1017 82 83 Login-denied 84 85 无效的用户名/口令 86 87 ORA-1403 88 89 No_data_found 90 91 SELECT INTO没有找到数据 92 93 ORA-1422 94 95 Too_many_rows 96 97 SELECT INTO 返回多行 98 99 ORA-1476 100 101 Zero-divide 102 103 试图被零除 104 105 ORA-1722 106 107 Invalid-NUMBER 108 109 转换一个数字失败 110 111 ORA-6500 112 113 Storage-error 114 115 内存不够引发的内部错误 116 117 ORA-6501 118 119 Program-error 120 121 内部错误 122 123 ORA-6502 124 125 Value-error 126 127 转换或截断错误 128 129 ORA-6504 130 131 Rowtype-mismatch 132 133 宿主游标变量与 PL/SQL变量有不兼容行类型 134 135 ORA-6511 136 137 CURSOR-already-OPEN 138 139 试图打开一个已处于打开状态的游标 140 141 ORA-6530 142 143 Access-INTO-null 144 145 试图为null 对象的属性赋值 146 147 ORA-6531 148 149 Collection-is-null 150 151 试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray上 152 153 ORA-6532 154 155 Subscript-outside-limit 156 157 对嵌套或varray索引得引用超出声明范围以外 158 159 ORA-6533 160 161 Subscript-beyond-count 162 163 对嵌套或varray 索引得引用大于集合中元素的个数. 164 165 166 167 对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。 168 169 170 171 例1:更新指定员工工资,如工资小于1500,则加100; 172 173 174 175 176 复制代码 177 DECLARE 178 v_empno employees.employee_id%TYPE := &empno; 179 v_sal employees.salary%TYPE; 180 BEGIN 181 SELECT salary INTO v_sal FROM employees WHERE employee_id = v_empno; 182 IF v_sal<=1500 THEN 183 UPDATE employees SET salary = salary + 100 WHERE employee_id=v_empno; 184 DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'员工工资已更新!'); 185 ELSE 186 DBMS_OUTPUT.PUT_LINE('编码为'||v_empno||'员工工资已经超过规定值!'); 187 END IF; 188 EXCEPTION 189 WHEN NO_DATA_FOUND THEN 190 DBMS_OUTPUT.PUT_LINE('数据库中没有编码为'||v_empno||'的员工'); 191 WHEN TOO_MANY_ROWS THEN 192 DBMS_OUTPUT.PUT_LINE('程序运行错误!请使用游标'); 193 WHEN OTHERS THEN 194 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 195 END; 196 复制代码 197 5.1.2 非预定义的异常处理 198 199 200 对于这类异常情况的处理,首先必须对非定义的ORACLE错误进行定义。步骤如下: 201 202 1. 在PL/SQL 块的定义部分定义异常情况: 203 204 205 206 207 208 <异常情况> EXCEPTION; 209 210 211 2. 将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句: 212 213 PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>); 214 215 216 3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。 217 218 219 220 221 222 例2:删除指定部门的记录信息,以确保该部门没有员工。 223 224 225 226 227 228 复制代码 229 INSERT INTO departments VALUES(50, 'FINANCE', 'CHICAGO'); 230 231 DECLARE 232 v_deptno departments.department_id%TYPE := &deptno; 233 deptno_remaining EXCEPTION; 234 PRAGMA EXCEPTION_INIT(deptno_remaining, -2292); 235 /* -2292 是违反一致性约束的错误代码 */ 236 BEGIN 237 DELETE FROM departments WHERE department_id = v_deptno; 238 EXCEPTION 239 WHEN deptno_remaining THEN 240 DBMS_OUTPUT.PUT_LINE('违反数据完整性约束!'); 241 WHEN OTHERS THEN 242 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 243 END; 244 复制代码 245 246 247 248 249 5.1.3 用户自定义的异常处理 250 251 当与一个异常错误相关的错误出现时,就会隐含触发该异常错误。用户定义的异常错误是通过显式使用 RAISE 语句来触发。当引发一个异常错误时,控制就转向到 EXCEPTION块异常错误部分,执行错误处理代码。 252 253 254 255 对于这类异常情况的处理,步骤如下: 256 257 1. 在PL/SQL 块的定义部分定义异常情况: 258 259 260 261 262 263 <异常情况> EXCEPTION; 264 265 266 2. RAISE <异常情况>; 267 268 269 270 271 272 3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。 273 274 275 276 277 278 例3:更新指定员工工资,增加100; 279 280 281 282 283 284 复制代码 285 DECLARE 286 v_empno employees.employee_id%TYPE :=&empno; 287 no_result EXCEPTION; 288 BEGIN 289 UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno; 290 IF SQL%NOTFOUND THEN 291 RAISE no_result; 292 END IF; 293 EXCEPTION 294 WHEN no_result THEN 295 DBMS_OUTPUT.PUT_LINE('你的数据更新语句失败了!'); 296 WHEN OTHERS THEN 297 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 298 END; 299 复制代码 300 301 302 303 304 5.1.4 用户定义的异常处理 305 306 307 308 调用DBMS_STANDARD(ORACLE提供的包)包所定义的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,它为应用程序提供了一种与ORACLE交互的方法。 309 310 311 312 RAISE_APPLICATION_ERROR 的语法如下: 313 314 315 316 RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] ); 317 318 319 这里的error_number 是从 –20,000 到 –20,999 之间的参数, 320 321 error_message 是相应的提示信息(< 2048 字节), 322 323 keep_errors 为可选,如果keep_errors =TRUE ,则新错误将被添加到已经引发的错误列表中。如果keep_errors=FALSE(缺省),则新错误将替换当前的错误列表。 324 325 326 327 例4:创建一个函数get_salary, 该函数检索指定部门的工资总和,其中定义了-20991和-20992号错误,分别处理参数为空和非法部门代码两种错误: 328 329 330 331 复制代码 332 CREATE TABLE errlog( 333 Errcode NUMBER, 334 Errtext CHAR(40)); 335 336 CREATE OR REPLACE FUNCTION get_salary(p_deptno NUMBER) 337 RETURN NUMBER 338 AS 339 v_sal NUMBER; 340 BEGIN 341 IF p_deptno IS NULL THEN 342 RAISE_APPLICATION_ERROR(-20991, ’部门代码为空’); 343 ELSIF p_deptno<0 THEN 344 RAISE_APPLICATION_ERROR(-20992, ’无效的部门代码’); 345 ELSE 346 SELECT SUM(employees.salary) INTO v_sal FROM employees 347 WHERE employees.department_id=p_deptno; 348 RETURN v_sal; 349 END IF; 350 END; 351 352 DECLARE 353 V_salary NUMBER(7,2); 354 V_sqlcode NUMBER; 355 V_sqlerr VARCHAR2(512); 356 Null_deptno EXCEPTION; 357 Invalid_deptno EXCEPTION; 358 PRAGMA EXCEPTION_INIT(null_deptno,-20991); 359 PRAGMA EXCEPTION_INIT(invalid_deptno, -20992); 360 BEGIN 361 V_salary :=get_salary(10); 362 DBMS_OUTPUT.PUT_LINE('10号部门工资:' || TO_CHAR(V_salary)); 363 364 BEGIN 365 V_salary :=get_salary(-10); 366 EXCEPTION 367 WHEN invalid_deptno THEN 368 V_sqlcode :=SQLCODE; 369 V_sqlerr :=SQLERRM; 370 INSERT INTO errlog(errcode, errtext) 371 VALUES(v_sqlcode, v_sqlerr); 372 COMMIT; 373 END inner1; 374 375 V_salary :=get_salary(20); 376 DBMS_OUTPUT.PUT_LINE('部门号为20的工资为:'||TO_CHAR(V_salary)); 377 378 BEGIN 379 V_salary :=get_salary(NULL); 380 END inner2; 381 382 V_salary := get_salary(30); 383 DBMS_OUTPUT.PUT_LINE('部门号为30的工资为:'||TO_CHAR(V_salary)); 384 385 EXCEPTION 386 WHEN null_deptno THEN 387 V_sqlcode :=SQLCODE; 388 V_sqlerr :=SQLERRM; 389 INSERT INTO errlog(errcode, errtext) VALUES(v_sqlcode, v_sqlerr); 390 COMMIT; 391 WHEN OTHERS THEN 392 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 393 END outer; 394 复制代码 395 396 397 398 399 例5:定义触发器,使用RAISE_APPLICATION_ERROR阻止没有员工姓名的新员式记录插入: 400 401 402 403 404 405 复制代码 406 CREATE OR REPLACE TRIGGER tr_insert_emp 407 BEFORE INSERT ON employees 408 FOR EACH ROW 409 BEGIN 410 IF :new.first_name IS NULL OR :new.last_name is null THEN 411 RAISE_APPLICATION_ERROR(-20000,'Employee must have a name.'); 412 END IF; 413 END; 414 复制代码 415 416 417 418 419 5.2 异常错误传播 420 421 由于异常错误可以在声明部分和执行部分以及异常错误部分出现,因而在不同部分引发的异常错误也不一样。 422 423 424 425 426 427 5.2.1 在执行部分引发异常错误 428 当一个异常错误在执行部分引发时,有下列情况: 429 430 l 如果当前块对该异常错误设置了处理,则执行它并成功完成该块的执行,然后控制转给包含块。 431 432 l 如果没有对当前块异常错误设置定义处理器,则通过在包含块中引发它来传播异常错误。然后对该包含块执行步骤1)。 433 434 435 436 437 438 5.2.2 在声明部分引发异常错误 439 如果在声明部分引起异常情况,即在声明部分出现错误,那么该错误就能影响到其它的块。比如在有如下的PL/SQL程序: 440 441 复制代码 442 DECLARE 443 name varchar2(12):='EricHu'; 444 其它语句 445 BEGIN 446 其它语句 447 EXCEPTION 448 WHEN OTHERS THEN 449 其它语句 450 END; 451 复制代码 452 453 454 例子中,由于Abc number(3)=’abc’; 出错,尽管在EXCEPTION中说明了WHEN OTHERS THEN语句,但WHEN OTHERS THEN也不会被执行。 但是如果在该错误语句块的外部有一个异常错误,则该错误能被抓住,如: 455 456 457 458 459 460 复制代码 461 BEGIN 462 DECLARE 463 name varchar2(12):='EricHu'; 464 其它语句 465 BEGIN 466 其它语句 467 EXCEPTION 468 WHEN OTHERS THEN 469 其它语句 470 END; 471 EXCEPTION 472 WHEN OTHERS THEN 473 其它语句 474 END; 475 复制代码 476 477 478 479 480 5.3 异常错误处理编程 481 482 在一般的应用处理中,建议程序人员要用异常处理,因为如果程序中不声明任何异常处理,则在程序运行出错时,程序就被终止,并且也不提示任何信息。下面是使用系统提供的异常来编程的例子。 483 484 485 486 5.4 在 PL/SQL 中使用 SQLCODE, SQLERRM异常处理函数 487 488 由于ORACLE 的错信息最大长度是512字节,为了得到完整的错误提示信息,我们可用 SQLERRM和 SUBSTR 函数一起得到错误提示信息,方便进行错误,特别是如果WHEN OTHERS异常处理器时更为方便。 489 490 491 492 SQLCODE 返回遇到的Oracle错误号, 493 494 SQLERRM 返回遇到的Oracle错误信息. 495 496 497 498 如: SQLCODE=-100 è SQLERRM=’no_data_found ‘ 499 500 SQLCODE=0 è SQLERRM=’normal, successfual completion’ 501 502 503 504 例6. 将ORACLE错误代码及其信息存入错误代码表 505 506 507 508 复制代码 509 CREATE TABLE errors (errnum NUMBER(4), errmsg VARCHAR2(100)); 510 511 DECLARE 512 err_msg VARCHAR2(100); 513 BEGIN 514 /* 得到所有 ORACLE 错误信息 */ 515 FOR err_num IN -100 .. 0 LOOP 516 err_msg := SQLERRM(err_num); 517 INSERT INTO errors VALUES(err_num, err_msg); 518 END LOOP; 519 END; 520 DROP TABLE errors; 521 复制代码 522 523 524 例7. 查询ORACLE错误代码; 525 526 527 528 529 530 复制代码 531 BEGIN 532 INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id) 533 VALUES(2222, 'Eric','Hu', SYSDATE, 20); 534 DBMS_OUTPUT.PUT_LINE('插入数据记录成功!'); 535 536 INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id) 537 VALUES(2222, '胡','勇', SYSDATE, 20); 538 DBMS_OUTPUT.PUT_LINE('插入数据记录成功!'); 539 EXCEPTION 540 WHEN OTHERS THEN 541 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 542 END; 543 复制代码 544 545 546 547 548 例8. 利用ORACLE错误代码,编写异常错误处理代码; 549 550 551 552 553 554 复制代码 555 DECLARE 556 empno_remaining EXCEPTION; 557 PRAGMA EXCEPTION_INIT(empno_remaining, -1); 558 /* -1 是违反唯一约束条件的错误代码 */ 559 BEGIN 560 INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id) 561 VALUES(3333, 'Eric','Hu', SYSDATE, 20); 562 DBMS_OUTPUT.PUT_LINE('插入数据记录成功!'); 563 564 INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id) 565 VALUES(3333, '胡','勇',SYSDATE, 20); 566 DBMS_OUTPUT.PUT_LINE('插入数据记录成功!'); 567 EXCEPTION 568 WHEN empno_remaining THEN 569 DBMS_OUTPUT.PUT_LINE('违反数据完整性约束!'); 570 WHEN OTHERS THEN 571 DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM); 572 END; 573
java数据类型
1 byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。 2 3 short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。 4 5 int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。 6 7 long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。 8 9 float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。 10 11 double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。 12 13 boolean:只有true和false两个取值。 14 15 char:16位,存储Unicode码,用单引号赋值。
1 2.Java中的常量 2 十六进制整型常量:以十六进制表示时,需以0x或0X开头,如0xff,0X9A。 3 4 八进制整型常量:八进制必须以0开头,如0123,034。 5 6 长整型:长整型必须以L作结尾,如9L,342L。 7 8 浮点数常量:由于小数常量的默认类型是double型,所以float类型的后面一定要加f(F)。同样带小数的变量默认为double类型。 9 10 如:float f; 11 12 f=1.3f;//必须声明f。 13 14 字符常量:字符型常量需用两个单引号括起来(注意字符串常量是用两个双引号括起来)。Java中的字符占两个字节。一些常用的转义字符: 15 16 ①\r表示接受键盘输入,相当于按下了回车键; 17 18 ②\n表示换行; 19 20 ③\t表示制表符,相当于Table键; 21 22 ④\b表示退格键,相当于Back Space键; 23 24 ⑤\'表示单引号; 25 26 ⑥\''表示双引号; 27 28 ⑦\\表示一个斜杠\。 29 30 31 32 3. 数据类型之间的转换 33 1).简单类型数据间的转换,有两种方式:自动转换和强制转换,通常发生在表达式中或方法的参数传递时。 34 35 自动转换 36 37 具体地讲,当一个较"小"数据与一个较"大"的数据一起运算时,系统将自动将"小"数据转换成"大"数据,再进行运算。而在方法调用时,实际参数较"小",而被调用的方法的形式参数数据又较"大"时(若有匹配的,当然会直接调用匹配的方法),系统也将自动将"小"数据转换成"大"数据,再进行方法的调用,自然,对于多个同名的重载方法,会转换成最"接近"的"大"数据并进行调用。这些类型由"小"到"大"分别为 (byte,short,char)--int--long--float—double。这里我们所说的"大"与"小",并不是指占用字节的多少,而是指表示值的范围的大小。 38 39 ①下面的语句可以在Java中直接通过: 40 41 byte b;int i=b; long l=b; float f=b; double d=b; 42 43 ②如果低级类型为char型,向高级类型(整型)转换时,会转换为对应ASCII码值,例如 44 45 char c='c'; int i=c; 46 47 System.out.println("output:"+i);输出:output:99; 48 49 ③对于byte,short,char三种类型而言,他们是平级的,因此不能相互自动转换,可以使用下述的强制类型转换。 50 51 short i=99 ; char c=(char)i; System.out.println("output:"+c);输出:output:c; 52 53 强制转换 54 55 将"大"数据转换为"小"数据时,你可以使用强制类型转换。即你必须采用下面这种语句格式: int n=(int)3.14159/2;可以想象,这种转换肯定可能会导致溢出或精度的下降。 56 57 2)表达式的数据类型自动提升, 关于类型的自动提升,注意下面的规则。 58 59 ①所有的byte,short,char型的值将被提升为int型; 60 61 ②如果有一个操作数是long型,计算结果是long型; 62 63 ③如果有一个操作数是float型,计算结果是float型; 64 65 ④如果有一个操作数是double型,计算结果是double型; 66 67 例, byte b; b=3; b=(byte)(b*3);//必须声明byte。 68 69 3)包装类过渡类型转换 70 71 一般情况下,我们首先声明一个变量,然后生成一个对应的包装类,就可以利用包装类的各种方法进行类型转换了。例如: 72 73 ①当希望把float型转换为double型时: 74 75 float f1=100.00f; 76 77 Float F1=new Float(f1); 78 79 double d1=F1.doubleValue();//F1.doubleValue()为Float类的返回double值型的方法 80 81 ②当希望把double型转换为int型时: 82 83 double d1=100.00; 84 85 Double D1=new Double(d1); 86 87 int i1=D1.intValue(); 88 89 简单类型的变量转换为相应的包装类,可以利用包装类的构造函数。即:Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value) 90 91 而在各个包装类中,总有形为××Value()的方法,来得到其对应的简单类型数据。利用这种方法,也可以实现不同数值型变量间的转换,例如,对于一个双精度实型类,intValue()可以得到其对应的整型变量,而doubleValue()可以得到其对应的双精度实型变量。 92 93 4)字符串与其它类型间的转换 94 95 其它类型向字符串的转换 96 97 ①调用类的串转换方法:X.toString(); 98 99 ②自动转换:X+""; 100 101 ③使用String的方法:String.volueOf(X); 102 103 字符串作为值,向其它类型的转换 104 105 ①先转换成相应的封装器实例,再调用对应的方法转换成其它类型 106 107 例如,字符中"32.1"转换double型的值的格式为:new Float("32.1").doubleValue()。也可以用:Double.valueOf("32.1").doubleValue() 108 109 ②静态parseXXX方法 110 111 String s = "1"; 112 113 byte b = Byte.parseByte( s ); 114 115 short t = Short.parseShort( s ); 116 117 int i = Integer.parseInt( s ); 118 119 long l = Long.parseLong( s ); 120 121 Float f = Float.parseFloat( s ); 122 123 Double d = Double.parseDouble( s ); 124 125 ③Character的getNumericValue(char ch)方法 126 127 5)Date类与其它数据类型的相互转换 128 129 整型和Date类之间并不存在直接的对应关系,只是你可以使用int型为分别表示年、月、日、时、分、秒,这样就在两者之间建立了一个对应关系,在作这种转换时,你可以使用Date类构造函数的三种形式: 130 131 ①Date(int year, int month, int date):以int型表示年、月、日 132 133 ②Date(int year, int month, int date, int hrs, int min):以int型表示年、月、日、时、分 134 135 ③Date(int year, int month, int date, int hrs, int min, int sec):以int型表示年、月、日、时、分、秒 136 137 在长整型和Date类之间有一个很有趣的对应关系,就是将一个时间表示为距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数。对于这种对应关系,Date类也有其相应的构造函数:Date(long date)。 138 139 获取Date类中的年、月、日、时、分、秒以及星期你可以使用Date类的getYear()、getMonth()、getDate()、getHours()、getMinutes()、getSeconds()、getDay()方法,你也可以将其理解为将Date类转换成int。 140 141 而Date类的getTime()方法可以得到我们前面所说的一个时间对应的长整型数,与包装类一样,Date类也有一个toString()方法可以将其转换为String类。 142 143 有时我们希望得到Date的特定格式,例如20020324,我们可以使用以下方法,首先在文件开始引入, 144 145 import java.text.SimpleDateFormat; 146 147 import java.util.*; 148 149 java.util.Date date = new java.util.Date(); 150 151 152 153 //如果希望得到YYYYMMDD的格式 154 155 SimpleDateFormat sy1=new SimpleDateFormat("yyyyMMDD"); 156 157 String dateFormat=sy1.format(date); 158 159 160 161 //如果希望分开得到年,月,日 162 163 SimpleDateFormat sy=new SimpleDateFormat("yyyy"); 164 165 SimpleDateFormat sm=new SimpleDateFormat("MM"); 166 167 SimpleDateFormat sd=new SimpleDateFormat("dd"); 168 169 String syear=sy.format(date); 170 171 String smon=sm.format(date); 172 173 String sday=sd.format(date); 174 175 总结:只有boolean不参与数据类型的转换 176 177 (1).自动类型的转换:a.常数在表数范围内是能够自动类型转换的 178 179 b.数据范围小的能够自动数据类型大的转换(注意特例) 180 181 int到float,long到float,long到double 是不会自动转换的,不然将会丢失精度 182 183 c.引用类型能够自动转换为父类的 184 185 d.基本类型和它们包装类型是能够互相转换的 186 187 (2).强制类型转换:用圆括号括起来目标类型,置于变量前 188 189 190 191 4.Java引用类型 192 Java有 5种引用类型(对象类型):类 接口 数组 枚举 标注 193 194 引用类型:底层结构和基本类型差别较大 195 196 JVM的内存空间:(1). Heap 堆空间:分配对象 new Student() 197 198 (2). Stack 栈空间:临时变量 Student stu 199 200 (3).Code 代码区 :类的定义,静态资源 Student.class 201 202 eg:Student stu = new Student(); //new 在内存的堆空间创建对象 203 204 stu.study(); //把对象的地址赋给stu引用变量 205 206 上例实现步骤:a.JVM加载Student.class 到Code区 207 208 b.new Student()在堆空间分配空间并创建一个Student实例 209 210 c.将此实例的地址赋值给引用s
字符处理
1 一、概述 2 3 Java是以String类型的对象来实现字符串。String是一个类,当创建一个String对象后,所创建的字符串是不能改变的。在需要使用可修改的字符串时,Java提供两个选择—StringBuffer和StringBuilder。注:声明为String引用的变量在任何时候都可以改变,以指向一些其他的String对象。 4 5 二、String构造函数 6 7 8 9 String s1="hello"与String s2=new String("hello")的区别: 10 11 String类在内存中管理一个字符串常量池(常量池的一部分),池中所有相同的字符串常量被合并,只占用一个空间。 12 13 String s1=”hello”,先看池中有没有hello,没有就创建一个hello字符串对象。即采用此方法创建0或者1个对象。 14 15 String s2=new String(“hello”),这里先在池中创建一个hello对象,同s1,然后new String()时,将hello对象复制到堆heap中,s2指向堆中的hello。采用此种方法时创建1或2个对象(当池中有hello时,创建一个对象)。 16 17 内存图如下: 18 19 20 21 三、String类的方法函数 22 23 String类有很多方法,这里只介绍几种常见的函数: 24 25 1、字符串的长度: 26 27 int length(); 28 29 2、字符串转换 30 31 每个类都会实现toString方法,因为它是由Obect定义的,对于大多数的自创建的类来说,通常要重写toString()并提供自己的字符串表达式。 32 33 eg: 34 35 复制代码 36 1 class Box 37 2 { 38 3 int x; 39 4 int y; 40 5 Box(int x,int y) 41 6 { 42 7 this.x=x; 43 8 this.y=y; 44 9 } 45 10 public String toString() 46 11 { 47 12 return "test_x"+"-----"+x+"\n"+"test_y"+"-----"+y; 48 13 } 49 14 } 50 15 public class Tset 51 16 { 52 17 public static void main(String[] args) 53 18 { 54 19 Box b=new Box(1,3); 55 20 System.out.println(b); 56 21 } 57 22 58 23 } 59 复制代码 60 显示结果为: 61 62 63 64 疑问:看了一下println的源码,不知道此处输出结果为何是如此? 65 66 复制代码 67 1 private void write(String s) { 68 2 try { 69 3 synchronized (this) { 70 4 ensureOpen(); 71 5 textOut.write(s); 72 6 textOut.flushBuffer(); 73 7 charOut.flushBuffer(); 74 8 if (autoFlush && (s.indexOf('\n') >= 0)) 75 9 out.flush(); 76 10 } 77 11 } 78 12 catch (InterruptedIOException x) { 79 13 Thread.currentThread().interrupt(); 80 14 } 81 15 catch (IOException x) { 82 16 trouble = true; 83 17 } 84 18 } 85 复制代码 86 3、字符抽取 87 88 charAt(): 返回指定索引处的 char 值。 89 90 getChars():一次抽取多个字符。 91 92 getBytes():将字符存储在字节数组里。 93 4、字符串比较 94 95 equals()和==:equals()方法是比较String对象中的字符,“==”运算符是比较两个对象是否引用同一实例。 96 97 eg: 98 99 复制代码 100 1 public class Test 101 2 { 102 3 public static void main(String[] args) 103 4 { 104 5 String s1=new String("hello");//创建2个对象,一个pool和一个堆里面 105 6 String s2="hello";//创建1个对象,s2指向pool里面的"hello"对象 106 7 String s3="hello";//创建0个对象,指向s2指向pool里面的那个对象 107 8 String s4=s2;//创建0个对象,指向s2,s3指向pool里面的那个对象 108 9 String s5=new String("hello");//创建1个对象在堆里面,注意,与s1没关系 109 10 110 11 System.out.println(s2=="hello");//true 111 12 System.out.println(s2==s3);//true,因为指向的都是pool里面的那个"hello" 112 13 System.out.println(s2==s4);//true,同上,那么s3和s4...:) 113 14 System.out.println(s1==s5);//false,很明显,false 114 15 System.out.println(s1==s2);//false,指向的对象不一样 115 16 System.out.println(s1=="hello");//false 116 17 System.out.println("---------------"); 117 18 s1=s2; 118 19 System.out.println(s1=="hello");//true 119 20 } 120 21 } 121 复制代码 122 执行结果: 123 124 125 126 复制代码 127 boolean startsWith(String prefix):判断给定的String是否以特定的字符串开始。 128 129 boolean startsWith(String prefix,int toffset):判断此字符从指定索引开始的字符串是否以指定的前缀开始。 130 131 endsWith():判断给定的String是否是以特定的字符串结束。 132 133 compareTo():用于比较字符串大小,并考虑大小写字母。 134 135 compareIgnoreCase():比较字符串大小并忽略大小写字母。 136 复制代码 137 5、查找字符串 138 139 isdexOf():查找字符或子串第一次出现的位置 140 141 lastIndexOf():查找字符或者子串最后出现的位置 142 6、更改字符串 143 144 因为String对象是不能改变的,当需要更改一个字符串时,就必须将他复制到一个StringBuffered中,后者使用下列方法,在更改后会构造一个新的字符串副本。 145 146 复制代码 147 substring(int startIndex):返回从startIndex开始到调用字符串结束的子串的一个副本 148 149 substring(int startIndex,int endIndex),指定起点和终点,返回这中间的字符串,不包括终点。 150 151 concat():连接两个字符串,与“+”运算符相同。 152 153 replace(char originial,char replacement):用一个字符在调用字符串中所有出现另一个字符的地方进行替换。 154 155 replace(CharSequence originial,CharSequence replacement):用一个字符串序列替换另一个字符串序列。 156 157 trim():返回调用字符串对象的一个副本,但是所有起始和结尾的空白符都被删除了(字符中间的空白符未被删除)。 158 复制代码 159 7、改变字符串中字符的大小写 160 161 toLowerCase():将所有字符改为小写 162 163 toUpperCase():将所有字符改为大写 164 四:StringBuffer类 165 166 StringBuffer是String的一个对等类,提供了字符串的许多功能,可增长、可改写。 167 168 这里只介绍几个StringBuffer类的方法函数: 169 170 1、append():将任何数据类型的字符串表示连接到调用的StringBuffer对象的末尾。 171 172 当定String对象使用“+”运算符时,经常要调用append方法。 173 174 StringBuffer s=new StringBuffer("hello"); 175 System.out.print(s.append(" world")); 176 2、inser(int index,String str):将一个字符串插入到另一个字符串中。 177 178 3、reverse():颠倒StringBuffer对象中的字符 179 180 4、delete(int startIndex,int endIndex),delete(int loc):调用对象中删除一串字符。 181 182 五、StringBuilder类 183 184 除了一个重要的区别之外,与StringBuffer等同,这个区别是他不是同步的,意味着他不是线程安全的,其优势是更快的性能,在使用多线程时必须使用StringBuffer。
方法的重写与重载
1 方法重载: 2 Java的方法重载,就是在类中可以创建多个方法,它们可以有相同的名字,但必须具有不同的参数,即或者是参数的个数不同,或者是参数的类型不同。调用方法时通过传递给它们的不同个数和类型的参数来决定具体使用哪个方法 3 4 示例代码: 5 6 7 8 复制代码 9 public class Test { 10 11 // 无返回值有有int形的参数 12 13 void receive(int i) { 14 System.out.println("i=" + i); 15 } 16 17 // 无返回值,有float形的参数 18 19 void receive(float f) { 20 System.out.println("f=" + f); 21 } 22 23 // 无返回值,有String形的参数 24 25 void receive(String s) { 26 System.out.println("s=" + s); 27 } 28 29 public static void main(String[] args) { 30 Test m = new Test(); 31 m.receive(1234); 32 m.receive(56.78f); 33 m.receive("方法重载"); 34 } 35 } 36 复制代码 37 38 39 注意: 40 41 Java的方法重载要求同名的方法必须有不同的参数表,仅有返回类型不同是不足以区分两个重载的方法。 42 43 44 方法重写: 45 在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。 46 示例代码: 47 48 复制代码 49 public class test { 50 public static void main(String[] args) { 51 new Derived(); 52 } 53 } 54 55 class Base { 56 private int i = 2; 57 58 public Base() { 59 display(); 60 } 61 62 public void display() { 63 System.out.println(i); 64 } 65 } 66 67 class Derived extends Base { 68 private int i = 22; 69 70 public Derived() { 71 i = 222; 72 } 73 74 public void display() { 75 System.out.println(i); 76 } 77 } 78 复制代码 79 80 81 super关键字: 82 若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。 如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。 83 84 85 总结: 86 方法重载: 87 1.必须具有不同的参数列表; 88 2.可以有不同的返回类型,只要参数不同就可以了。 89 3.可以有不同的访问修饰符。 90 方法重写: 91 1.参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。 92 2.返回类型必须相同。 93 3.访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private) 94 4.方法重写主要优点是能够定义某个子类独有的特征。这也是多态的体现。
数组
1 数组?什么是数组?在我印象中的数组是应该这样的:通过new关键字创建并组装他们,通过使用整形索引值访问它的元素,并且它的尺寸是不可变的! 2 3 但是这只是数组的最表面的东西!深一点?就是这样:数组是一个简单的复合数据类型,它是一系列有序数据的集合,它当中的每一个数据都具有相同的数据类型,我们通过数组名加上一个不会越界下标值来唯一确定数组中的元素。 4 5 还有更深的,那就是数组是一个特殊的对象!!(对于这个LZ理解的不是很好,对JVM也没有看,所以见解有限)。以下参考文献:http://developer.51cto.com/art/201001/176671.htm、http://www.blogjava.net/flysky19/articles/92763.html?opt=admin 6 7 不管在其他语言中数组是什么,在java中它就是对象。一个比较特殊的对象。 8 9 复制代码 10 public class Test { 11 public static void main(String[] args) { 12 int[] array = new int[10]; 13 System.out.println("array的父类是:" + array.getClass().getSuperclass()); 14 System.out.println("array的类名是:" + array.getClass().getName()); 15 } 16 } 17 -------Output: 18 array的父类是:class java.lang.Object 19 array的类名是:[I 20 复制代码 21 从上面示例可以看出,数组的是Object的直接子类,它属于“第一类对象”,但是它又与普通的java对象存在很大的不同,从它的类名就可以看出:[I,这是什么东东??在JDK中我就没有找到这个类,话说这个"[I”都不是一个合法标识符。怎么定义成类啊?所以我认为SUM那帮天才肯定对数组的底层肯定做了特殊的处理。 22 23 我们再看如下示例: 24 25 复制代码 26 public class Test { 27 public static void main(String[] args) { 28 int[] array_00 = new int[10]; 29 System.out.println("一维数组:" + array_00.getClass().getName()); 30 int[][] array_01 = new int[10][10]; 31 System.out.println("二维数组:" + array_01.getClass().getName()); 32 33 int[][][] array_02 = new int[10][10][10]; 34 System.out.println("三维数组:" + array_02.getClass().getName()); 35 } 36 } 37 -----------------Output: 38 一维数组:[I 39 二维数组:[[I 40 三维数组:[[[I 41 复制代码 42 通过这个实例我们知道:[代表了数组的维度,一个[表示一维,两个[表示二维。可以简单的说数组的类名由若干个'['和数组元素类型的内部名称组成。不清楚我们再看: 43 44 复制代码 45 public class Test { 46 public static void main(String[] args) { 47 System.out.println("Object[]:" + Object[].class); 48 System.out.println("Object[][]:" + Object[][].class); 49 System.err.println("Object[][][]:" + Object[][][].class); 50 System.out.println("Object:" + Object.class); 51 } 52 } 53 ---------Output: 54 Object[]:class [Ljava.lang.Object; 55 Object[][]:class [[Ljava.lang.Object; 56 Object[][][]:class [[[Ljava.lang.Object; 57 Object:class java.lang.Object 58 复制代码 59 从这个实例我们可以看出数组的“庐山真面目”。同时也可以看出数组和普通的Java类是不同的,普通的java类是以全限定路径名+类名来作为自己的唯一标示的,而数组则是以若干个[+L+数组元素类全限定路径+类来最为唯一标示的。这个不同也许在某种程度上说明了数组也普通java类在实现上存在很大的区别,也许可以利用这个区别来使得JVM在处理数组和普通java类时作出区分。 60 61 我们暂且不论这个[I是什么东东,是由谁来声明的,怎么声明的(这些我现在也不知道!但是有一点可以确认:这个是在运行时确定的)。先看如下: 62 63 复制代码 64 public class Test { 65 public static void main(String[] args) { 66 int[] array = new int[10]; 67 Class clazz = array.getClass(); 68 System.out.println(clazz.getDeclaredFields().length); 69 System.out.println(clazz.getDeclaredMethods().length); 70 System.out.println(clazz.getDeclaredConstructors().length); 71 System.out.println(clazz.getDeclaredAnnotations().length); 72 System.out.println(clazz.getDeclaredClasses().length); 73 } 74 } 75 ----------------Output: 76 0 77 0 78 0 79 0 80 0 81 复制代码 82 从这个运行结果可以看出,我们亲爱的[I没有生命任何成员变量、成员方法、构造函数、Annotation甚至连length成员变量这个都没有,它就是一个彻彻底底的空类。没有声明length,那么我们array.length时,编译器怎么不会报错呢?确实,数组的length是一个非常特殊的成员变量。我们知道数组的是Object的直接之类,但是Object是没有length这个成员变量的,那么length应该是数组的成员变量,但是从上面的示例中,我们发现数组根本就没有任何成员变量,这两者不是相互矛盾么? 83 84 复制代码 85 public class Main { 86 public static void main(String[] args) { 87 int a[] = new int[2]; 88 int i = a.length; 89 } 90 } 91 复制代码 92 打开class文件,得到main方法的字节码: 93 94 复制代码 95 0 iconst_2 //将int型常量2压入操作数栈 96 1 newarray 10 (int) //将2弹出操作数栈,作为长度,创建一个元素类型为int, 维度为1的数组,并将数组的引用压入操作数栈 97 3 astore_1 //将数组的引用从操作数栈中弹出,保存在索引为1的局部变量(即a)中 98 4 aload_1 //将索引为1的局部变量(即a)压入操作数栈 99 5 arraylength //从操作数栈弹出数组引用(即a),并获取其长度(JVM负责实现如何获取),并将长度压入操作数栈 100 6 istore_2 //将数组长度从操作数栈弹出,保存在索引为2的局部变量(即i)中 101 7 return //main方法返回 102 复制代码 103 在这个字节码中我们还是没有看到length这个成员变量,但是看到了这个:arraylength ,这条指令是用来获取数组的长度的,所以说JVM对数组的长度做了特殊的处理,它是通过arraylength这条指令来实现的。 104 105 二、数组的使用方法 106 通过上面算是对数组是什么有了一个初步的认识,下面将简单介绍数组的使用方法。 107 108 数组的使用方法无非就是四个步骤:声明数组、分配空间、赋值、处理。 109 110 声明数组:就是告诉计算机数组的类型是什么。有两种形式:int[] array、int array[]。 111 112 分配空间:告诉计算机需要给该数组分配多少连续的空间,记住是连续的。array = new int[10]; 113 114 赋值:赋值就是在已经分配的空间里面放入数据。array[0] = 1 、array[1] = 2……其实分配空间和赋值是一起进行的,也就是完成数组的初始化。有如下三种形式: 115 116 int a[] = new int[2]; //默认为0,如果是引用数据类型就为null 117 int b[] = new int[] {1,2,3,4,5}; 118 int c[] = {1,2,3,4,5}; 119 处理:就是对数组元素进行操作。通过数组名+有效的下标来确认数据。
构造器重载
1 二、构造器重载: 2 构造器可以认为它是个特殊的方法:无需声明返回值类型,如果声明了返回值类型则变成普通方法; 3 4 构造器的作用:构造器并不是创建对象,而是初始化实例,严格来说对象是new出来的; 5 6 构造器重载:完全类似于方法重载 -- 两同(同一个类、方法名相同)-- 一异(形参列表不同) 7 8 9 10 复制代码 11 1 public class Monkey{ 12 2 private String name; 13 3 private double weight; 14 4 private int age; 15 5 16 6 //提供带两个参数的构造器 17 7 public Monkey(String name , double weight){ 18 8 this.name = name; 19 9 this.weight = weight; 20 10 } 21 11 22 12 //提供带三个参数的构造器,构造器的作用是用来初始化实例的 23 13 public Monkey(String name , double weight , int age){ 24 14 this(name,weight); 25 15 this.age = age; 26 16 } 27 17 28 18 public void info(){ 29 19 System.out.println("这是一只猴子,它的名字是:" + name + 30 20 ",体重是:" + weight + ",年龄是:" + age); 31 21 } 32 22 33 23 public static void main(String[] args){ 34 24 Monkey m = new Monkey("小金刚",100); 35 25 m.info(); 36 26 Monkey m2 = new Monkey("金刚",300,20); 37 27 m2.info(); 38 28 } 39 29 } 40 复制代码
多肽
1 抽象类:主要作用----->封装 2 3 在使用抽象类时需要注意几点: 4 1、抽象类不能被实例化(像刚才的动物,实例化是没有任何意义的),实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。 5 6 2、抽象方法必须由子类来进行重写。 7 8 3、如果类中包含抽象方法,该类必须要定义成抽象类,不管是否还包含有其他方法。 9 10 4、抽象类中可以包含具体的方法,当然也可以不包含抽象方法。 11 12 5、子类中的抽象方法不能与父类的抽象方法同名。 13 14 6、abstract不能与final并列修饰同一个类。 15 16 7、abstract 不能与private、static、final或native并列修饰同一个方法。 17 18 19 20 21 22 对多肽的理解: 23 24 多肽的三个含义:1)子类都能以父类的身份出现 25 2)子类以父类的身份出现,但是做事情时,还是用自己的方式来实现。 26 3)子类以父类的身份出现时,自己特有的属性和行为将不能被使用。 27 (来自百度百科) 28 29 实例: 30 复制代码 31 1 package SecondWeekSixthDay; 32 2 //对多肽的学习 33 3 34 4 //抽象类 35 5 abstract class Animal { 36 6 abstract void eat();//抽象方法 37 7 } 38 8 39 9 //子类 40 10 class Cat extends Animal{ 41 11 public void eat(){/*必须继承父类的抽象方法*/ 42 12 System.out.println("猫吃鱼"); 43 13 } 44 14 public void catchMouse(){/*子类自身独有的方法*/ 45 15 System.out.println("抓老鼠"); 46 16 } 47 17 } 48 18 49 19 class Dog extends Animal{ 50 20 public void eat(){ 51 21 System.out.println("吃骨头"); 52 22 } 53 23 public void catchMouse(){ 54 24 System.out.println("看家"); 55 25 } 56 26 } 57 27 58 28 class Pig extends Animal{ 59 29 public void eat(){ 60 30 System.out.println("睡觉"); 61 31 } 62 32 void sleep(){ 63 33 System.out.println("睡觉"); 64 34 } 65 35 } 66 36 67 37 68 38 69 39 /*相当于测试类*/ 70 40 public class DuoTaiDemo{/*方法体*/ 71 41 public static void main(String[] args){/*main函数入口*/ 72 42 73 43 Animal animal=new Cat();/*作用:调用其他类来定义成一个新类*/ 74 44 animal.eat();/*调用这个类的eat方法*/ 75 45 //animal.catchMouse();/*因抽象类没有这个方法,因此无法调用*/ 76 46 //Cat();/*不能使用调用方法。因方法体中不存在Cat方法*/ 77 47 78 48 Animal animal2=new Dog(); 79 49 animal2.eat(); 80 50 81 51 Animal animal3=new Pig(); 82 52 animal3.eat(); 83 53 } 84 54 85 55 86 56 }
集合
范型
1 是范型里面的通配符,extends, super只是提供上下限的信息给编译起, 通配符有集合的概念在里面,Fanxin< ? extends Base>, ?类型可能是Base的任何子类,所以我们不能有赋值操作,因为子类和子类是不同的类型,只是子类可以替换父类而已,所以可以按父类来读取值, Fanxin<? super A>, ?类型是A的超类, 所以我们可以将A的任何子类赋值给他,这样是安全的,但是读取的时候,是无法知道这是什么类型的,但是java类都是Object类的扩展, 所以可以获取值赋给obj对象, Object obj = fanxin.get(); 如果要赋值给其他对象那么只有强制类型转换了。
类的加载与反射
1 当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三个步骤来对该类进行初始化。 2 3 类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,即当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象 4 5 系统中所有的类实际上也是实例,都是java.lang.Class的实例 6 7 类的加载由类加载器完成,类加载通常由JVM提供。JVM提供的类加载器称为系统类加载器。 8 9 开发者可以通过继承ClassLoader基类来创建自己的类加载器 10 11 记载类的来源: 12 13 1、从本地文件系统加载class文件 14 15 2、从JAR包加载class文件 16 17 3、通过网络加载class文件 18 19 4、把一个Java源文件动态编译,并执行加载 20 21 Java虚拟机规范允许系统预先加载某些类
反射
1 反射机制是什么 2 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 3 4 反射机制能做什么 5 反射机制主要提供了以下功能: 6 7 在运行时判断任意一个对象所属的类; 8 在运行时构造任意一个类的对象; 9 在运行时判断任意一个类所具有的成员变量和方法; 10 在运行时调用任意一个对象的方法; 11 生成动态代理。
多线程
1 java中要想实现多线程,有两种手段,一种是继续Thread类,另外一种是实现Runable接口
程对象是可以产生线程的对象。比如在Java平台中Thread对象,Runnable对象。线程,是指正在执行的一个指点令序列。在java平台上是指从一个线程对象的start()开始,运行run方法体中的那一段相对独立的过程。相比于多进程,多线程的优势有:
(1)进程之间不能共享数据,线程可以;
(2)系统创建进程需要为该进程重新分配系统资源,故创建线程代价比较小;
(3)Java语言内置了多线程功能支持,简化了java多线程编程。
线程同步
1 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏。
类加载
1 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。
异常处理
1 try { 2 File file = new File("d:/a.txt"); 3 if(!file.exists()) 4 file.createNewFile(); 5 } catch (IOException e) { 6 // TODO: handle exception 7 }
1 hrows和thow关键字 2 3 1)throws出现在方法的声明中,表示该方法可能会抛出的异常,然后交给上层调用它的方法程序处理,允许throws后面跟着多个异常类型; 4 5 2)一般会用于程序出现某种逻辑时程序员主动抛出某种特定类型的异常。throw只会出现在方法体中,当方法在执行过程中遇到异常情况时,将异常信息封装为异常对象,然后throw出去。throw关键字的一个非常重要的作用就是 异常类型的转换(会在后面阐述道)。 6 7 throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常对象。两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由方法去处理异常,真正的处理异常由此方法的上层调用处理。
1 面向对象 2 3 面向对象(Object Oriented)是一种新兴的程序设计方法,或者是一种新的程序设计规范(paradigm),其基本思想是使用对象、类、继承、封装、多态等基本概念来进行程序设计。从现实世界中客观存在的事物(即对象)出发来构造软件系统,并且在系统构造中尽可能运用人类的自然思维方式。 4 5 2、对象 6 7 对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。一个对象由一组属性和对这组属性进行操作的一组服务组成。 8 9 类的实例化可生成对象,一个对象的生命周期包括三个阶段:生成、使用、消除。 10 11 当不存在对一个对象的引用时,该对象成为一个无用对象。Java的垃圾收集器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。当系统内存用尽或调用System.gc( )要求垃圾回收时,垃圾回收线程与系统同步运行。 12 13 3、类 14 15 类是具有相同属性和方法的一组对象的集合,它为属于该类的所有对象提供了统一的抽象描述,其内部包括属性和方法两个主要部分。在面向对象的编程语言中,类是一个独立的程序单位,它应该有一个类名并包括属性和方法两个主要部分。 16 17 Java中的类实现包括两个部分:类声明和类体。 18 19 类声明 20 21 1 22 [public][abstract|final] class className [extends superclassName] [implements interfaceNameList]{……} 23 其中,修饰符public,abstract,final 说明了类的属性,className为类名,superclassName为类的父类的名字,interfaceNameList为类所实现的接口列表。 24 25 类体 26 27 1 28 2 29 3 30 4 31 5 32 6 33 class className{ 34 [public | protected | private ] [static] [final] [transient] [volatile] type variableName;//成员变量 35 [public | protected | private ] [static] [final | abstract] [native] [synchronized] returnType methodName([paramList]) [throws exceptionList]{ 36 statements 37 }//成员方法 38 } 39 成员变量限定词的含义: 40 41 static: 静态变量(类变量) 42 final: 常量;transient: 暂时性变量,用于对象存档,用于对象的串行化 43 volatile: 贡献变量,用于并发线程的共享 44 方法的实现也包括两部分内容:方法声明和方法体。 45 46 方法声明 47 48 方法声明中的限定词的含义: 49 50 static: 类方法,可通过类名直接调用 51 abstract: 抽象方法,没有方法体 52 final: 方法不能被重写 53 native: 集成其它语言的代码 54 synchronized: 控制多个并发线程的访问 55 方法声明包括方法名、返回类型和外部参数。其中参数的类型可以是简单数据类型,也可以是复合数据类型(又称引用数据类型)。 56 对于简单数据类型来说,java实现的是值传递,方法接收参数的值,但不能改变这些参数的值。如果要改变参数的值,则用引用数据类型,因为引用数据类型传递给方法的是数据在内存中的地址,方法中对数据的操作可以改变数据的值。 57 58 方法体 59 60 方法体是对方法的实现,它包括局部变量的声明以及所有合法的Java指令。方法体中声明的局部变量的作用域在该方法内部。若局部变量与类的成员变量同名,则类的成员变量被隐藏。 61 为了区别参数和类的成员变量,我们必须使用this。this用在一个方法中引用当前对象,它的值是调用该方法的对象。返回值须与返回类型一致,或者完全相同,或是其子类。当返回类型是接口时,返回值必须实现该接口。 62 63 构造方法 64 65 构造方法是一个特殊的方法。Java 中的每个类都有构造方法,用来初始化该类的一个对象。 66 构造方法具有和类名相同的名称,而且不返回任何数据类型。 67 重载经常用于构造方法。 68 构造方法只能由new运算符调用 69 4、面向对象的基本特性 70 71 封装 72 73 封装性就是尽可能的隐藏对象内部细节,对外形成一道边界,只保留有限的接口和方法与外界进行交互。封装的原则是使对象以外的部分不能随意的访问和操作对象的内部属性,从而避免了外界对对象内部属性的破坏。 74 75 可以通过对类的成员设置一定的访问权限,实现类中成员的信息隐藏。 76 77 private:类中限定为private的成员,只能被这个类本身访问。如果一个类的构造方法声明为private,则其它类不能生成该类的一个实例。 78 default:类中不加任何访问权限限定的成员属于缺省的(default)访问状态,可以被这个类本身和同一个包中的类所访问。 79 protected:类中限定为protected的成员,可以被这个类本身、它的子类(包括同一个包中以及不同包中的子类)和同一个包中的所有其他的类访问。 80 public:类中限定为public的成员,可以被所有的类访问。 81 82 83 继承 84 85 子类的对象拥有父类的全部属性与方法,称作子类对父类的继承。 86 87 Java中父类可以拥有多个子类,但是子类只能继承一个父类,称为单继承。 88 继承实现了代码的复用。 89 Java中所有的类都是通过直接或间接地继承java.lang.Object类得到的。 90 子类不能继承父类中访问权限为private的成员变量和方法。 91 子类可以重写父类的方法,即命名与父类同名的成员变量。 92 Java中通过super来实现对父类成员的访问,super用来引用当前对象的父类。super 的使用有三种情况: 93 94 访问父类被隐藏的成员变量,如:super.variable; 95 调用父类中被重写的方法,如:super.Method([paramlist]),super()调用父类构造方法; 96 调用父类的构造函数,如:super([paramlist]); 97 多态 98 99 对象的多态性是指在父类中定义的属性或方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为。这使得同一个属性或方法在父类及其各个子类中具有不同的语义。例如:"几何图形"的"绘图"方法,"椭圆"和"多边形"都是"几何图"的子类,其"绘图"方法功能不同。 100 101 Java的多态性体现在两个方面:由方法重载实现的静态多态性(编译时多态)和方法重写实现的动态多态性(运行时多态)。 102 103 编译时多态:在编译阶段,具体调用哪个被重载的方法,编译器会根据参数的不同来静态确定调用相应的方法。 104 运行时多态:由于子类继承了父类所有的属性(私有的除外),所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替。一个对象可以通过引用子类的实例来调用子类的方法。 105 重载(Overloading) 106 107 方法重载是让类以统一的方式处理不同数据类型的手段。 108 一个类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法。 109 返回值类型可以相同也可以不相同,无法以返回型别作为重载函数的区分标准。 110 重写(Overriding) 111 112 子类对父类的方法进行重新编写。如果在子类中的方法与其父类有相同的的方法名、返回类型和参数表,我们说该方法被重写 (Overriding)。 113 如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。 114 子类函数的访问修饰权限不能低于父类的。 115 116 117 分类: 1. Java
python
数据类型。
1 准数据类型 2 3 Number(数字) 4 String(字符串) 5 List(列表) 6 Tuple(元组) 7 Set(集合) 8 Dictionary(字典) 9 Python3 的六个标准数据类型中: 10 11 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组); 12 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。 13 ———————————————— 14 版权声明:本文为CSDN博主「When happiness knock」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 15 原文链接:https://blog.csdn.net/weixin_43883625/article/details/100036892
迭代
1 给定一个list或者tuple,用for循环来进行遍历访问,称为迭代 2 判断是否可以迭代 3 4 form collections import Iterable 5 isinstance('ABC',Iterable) 6 //判断ABC是否可以迭代 7 1 8 2 9 3 10 给定list 11 12 list('a':1,'b':2,'c':3) 13 //访问key 14 for key in d: 15 print(key) 16 for value in d.values(): 17 print(value) 18 for k,v in d.items(): 19 print(k,v); 20 1 21 2 22 3 23 4 24 5 25 6 26 7 27 8 28 对于字符串 29 30 for ch in 'ABC' 31 print(ch) 32 1 33 2 34 对于二维 35 36 d=[[1,1],[1,2],[1,3]] 37 for x,y in d: 38 print(x,y) 39 1 40 2 41 3 42 对于没有下标 43 44 //运用enumerate函数将list变为索引函数对 45 for i,value in enumerate(['A','B','c']): 46 print(i,value) 47 ———————————————— 48 版权声明:本文为CSDN博主「fourous」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 49 原文链接:https://blog.csdn.net/fourous/article/details/79600407