JAVA经典面试题-数据库

1. 存储过程的作用?

存储过程可以使得对数据库的管理、以及显示关于数据库及其用户信息的工作容易得多。存储过程是 SQL 语句和可选控制流语句的预编译集合, 以一个名称存储并作为一个单元处理。存储过程存储在数据库内,可由应用程序通过一个调用执行,

而且允许用户声明变量、有条件执行以及其它强大的编程功能。 

存储过程可包含程序流、逻辑以及对数据库的查询。它们可以接受参数、输出参数、返回单个或多个结果集以及返回值。 

可以出于任何使用 SQL 语句的目的来使用存储过程,它具有以下优点: 

可以在单个存储过程中执行一系列 SQL 语句。 

可以从自己的存储过程内引用其它存储过程,这可以简化一系列复杂语句。 

存储过程在创建时即在服务器上进行编译,所以执行起来比单个 SQL 语句快。

2. sqlserveroracle数据库的性能优化

3.1选用适合的ORACLE优化器

        ORACLE的优化器共有3:  

     a. RULE (基于规则) b. COST (基于成本) c. CHOOSE (选择性)

       在缺省情况下,ORACLE采用CHOOSE 优化器为了避免那些不必要的全表扫描(full table scan) , 你必须尽量避免使用CHOOSE优化器,而直接采用基于规则或者基于成本的优化器.

访问Table的方式

3.2ORACLE 采用两种访问表中记录的方式

     a. 全表扫描                                                    

        全表扫描就是顺序地访问表中每条记录. ORACLE采用一次读入多个数据块(database block)的方式优化全表扫描.

     b. 通过ROWID访问表                                         

          你可以采用基于ROWID的访问方式情况,提高访问表的效率,RowId包含了表中记录的物理位置信息.ORACLE采用索引(INDEX)实现了数据和存放数据的物理位置(RowId)之间的联系。 通常索引提供了快速访问ROWID的方法,因此那些基于索引列的查询就可以得到性能上的提高.

3.3. 选择最有效率的表名顺序(只在基于规则的优化器中有效

3.4. WHERE子句中的连接顺序.

       ORACLE采用自下而上的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之前那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾.

3.5. SELECT子句中避免使用 ‘ * ‘                           

       当你想在SELECT子句中列出所有的COLUMN,使用动态SQL列引用 ‘*’ 是一个方便的方法.不幸的是,这是一个非常低效的方法实际上,ORACLE在解析的过程中会将’*’ 依次转换成所有的列名这个工作是通过查询数据字典完成的这意味着将耗费更多的时间

3.6. 减少访问数据库的次数

       当执行每条SQL语句时, ORACLE在内部执行了许多工作解析SQL语句估算索引的利用率绑定变量 读数据块等等由此可见减少访问数据库的次数 就能实际上减少 ORACLE的工作量.

3.7. 整合简单,无关联的数据库访问 

       如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)

3.8. 使用表的别名(Alias) 

       当在SQL语句中连接多个表时请使用表的别名并把别名前缀于每个Column.这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误.

3.9. 对经常要查询的字段可以建立一个视图

3.10. 在表中的某个字段上建立索引,可以提高检索速度。

3. 模糊查询可以用索引吗?

     (1)如果模糊查询是下边这个样子:where a like '*****%',就可以用索引;

       如果模糊查询是 where a like '%****'的形式,就不能使用索引!

(2)建全文索引后使用constain

4. sql的关键字及其一些函数

    sql关键字:all, alter, as, asc, container, create, delete, desc, drop, first, from, in, index,

               insert, into, join, last, on, schema, select, selectschema, selectsecurity, table,

               to, update, updateidentity, updateowner, updatesecurity, user, with;

    函数:Avg(), Count(), First(), Last(), Max(), Min(), Sum(),StDev()

          StDevP()[StDev,StDevP返回总体或总体样本的标准偏差的估计值], Var(), VarP()[Var,VarP返回一个总体或总体样本的方差的估计值

          

ODBC标量函数:

    1. 字符串函数 ASCII   LENGTH  RTRIM   CHAR  LOCATE   SPACE CONCAT    LTRIM  SUBSTRING  LCASE  RIGHT  UCASE   LEFT

    2. 数字函数 ABS  FLOOR  SIN  ATAN  LOG  SQRT CEILING   POWER      TAN          COS  RAND   MOD  EXP  SIGN 

    3. 时间和日期函数  CURDATE   DAYOFYEAR  MONTH  CURTIME   YEAR        WEEK  NOW  HOUR QUARTER  DAYOFMONTH   MINUTE    MONTHNAME   DAYOFWEEK   SECOND    DAYNAME 

    4. 数据类型变换    CONVERT

ORACLE

5. Oracle中的事务

Oracle在缺省情况下任何一个DML语句都会开始一个事务,直到用户发出CommitRollback操作,这个事务才会结束。在Oracle中,执行DDL语句(Create TableCreate View)时,会在执行之前自动发出一个Commit命令,并在随后发出一个Commit或者Rollback命令。

(1) 提交事务 

提交一事务,即将在事务中由SQL语句所执行的改变永久化。在提交前,ORACLE已有下列情况: 
   在SGA的回滚段缓冲区已生成回滚段记录,回滚信息包含有所修改值的老值。 
   在SGA的日志缓冲区已生成日志项。这些改变在事务提交前可进入磁盘。 
   对SGA的数据库缓冲区已作修改,这些修改在事务真正提交之前可进入磁盘。 
   在事务提交之后,有下列情况: 
   对于与回滚段相关的内部事务表记录提交事务,并赋给一个相应的唯一系统修改号(SCN),记录在表中。 
   在SGA的日志缓冲区中日志项由LGWR进程写入到在线日志文件, 这是构成提交事务的原子事务。 
   在行上和表上的封锁被释放。 
   该事务标志为完成 。 
   注意:对于提交事务的数据修改不必由DBWR后台进程立即写入数据文件,可继续存储在SGA的数据库缓冲区中,在最有效时将其写入数据文件。

(2) 回滚事务 

 回滚事务的含义是撤消未提交事务中的SQL语句所作的对数据修改。ORALCE允许撤消未提交的整个事务,也允许撤消部分。 
   在回滚整个事务(没有引用保留点)时,有下列情况: 
   在事务中所有SQL语句作的全部修改,利用相应的回滚段被撤消。 
   所有数据的事务封锁被释放。 
   事务结束。 
   当事务回滚到一保留点(具有SAVEPOINT)时,有下列情况: 
   仅在该保留点之后执行的语句被撤消。 
   该指定的保留点仍然被保留,该保留点之后所建立的保留点被删除。 
   自该保留点之后所获取的全部表封锁和行封锁被释放,但指定的保留点以前所获取的全部数据封锁继续保持。 
   该事务仍可继续。 

(3) 保留点 

保留点(savepoint)是在一事务范围内的中间标志,经常用于将一个长的事务划分为小的部分。保留点可标志长事务中的任何点,允许可回滚该点之后的工作。在应用程序中经常使用保留点;例如一过程包含几个函数,在每个函数前可建立一个保留点,如果函数失败,很容易返回到每一个函数开始的情况。在回滚到一个保留点之后,该保持点之后所获得的数据封锁被释放。

6. 视图在什么情况下可以对其,删除,修改操作:

DML操作应遵循的原则:

1.简单视图可以执行DML操作;

2.在视图包含GROUP 函数,GROUP BY子句,DISTINCT关键字时不能删除数据行;

3.在视图不出现下列情况时可通过视图修改基表数据或插入数据:

 a.视图中包含GROUP 函数,GROUP BY子句,DISTINCT关键字;

 b.使用表达式定义的列;

 c.ROWNUM伪列。

 d.基表中未在视图中选择的其他列定义为非空且无默认值。

WITH CHECK OPTION 子句限定:

通过视图执行的INSERTSUPDATES操作不能创建该视图检索不到的数据行,

因为它会对插入或修改的数据行执行完整性约束和数据有效性检查。

视图的删除:

DROP VIEW  VIEW_NAME语句删除视图。

删除视图的定义不影响基表中的数据。

只有视图所有者和具备DROP VIEW权限的用户可以删除视图。

视图被删除后,基于被删除视图的其他视图或应用将无效。

7. oracle中各种连接的写法:

内连接,外连接 ,左外连接,右外连接
以上几种连接一般用于多表之间复杂的查询,
 下面先说说内连接,也即相等连接,如右两张表 dept employee
dept里有字段deptiddeptnameemployee有字段empnodeptidenamesalage
那连接查询语句如下:select A.* ,B.* from dept A,employee B where A.deptid=B.deptid
一般出现这种情况的是一张是主表,另一张是子表,主表的主键作为子表的外键,显示结果按照子表的显示, 内连接简单,这里就不多说了
 外连接在oralce里用(+)表示,先看例子
select empno,ename,sal,emp.deptno,dept.deptno from emp,dept where emp.deptno(+) =dept.deptno
这是一个右连接
看下面的例子
select empno,ename,sal,emp.deptno,dept.deptno from emp,dept where dept.no=emp.deptno(+)
这是一个左连接
两个查询显示的查询结果是一样的,刚开始学oracle的时候很多人都很难明白这个,现在有个笨办法,
大家不防记下来,(+)出现查询条件的左边即右连接,出现在右边即左连接。(+)可以放在左边也可以
放在右边,但是一定要放在缺少条件的那一边,如上面的例子中,如果公司最近准备成立一个新的部门,
测试部门,但现在还没有招新员工,而现在Boss想知道公司有知道公司的员工在那个部门并且想知道
没有员工的部门,我们可以用上面的查询语句实现。
左外连接(left outer join)和右外连接(reght outer join)如同上面的外连接,查询的结果是一样的。
左外连接:select empno,ename,sal,emp.deptno,dept.deptno from dept left outer join emp on (emp.deptno=dept.deptno)
右外连接:select empno,ename,sal,emp.deptno,dept.deptno from emp reight outer join dept on (emp.deptno=dept.deptno)
以上显示的结果和外连接查询出来的结果是一样的 ,只是写法不一样而已,实际工作中外连接用的比较多,没有必要都要去用它,但是概念大家一定要了解。
全外关联 :FULL OUTER JOIN
SELECT e.last_name, e.department_id, d.department_name  
FROM employees e  
FULL OUTER JOIN departments d  
ON (e.department_id = d.department_id);  
结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。

8. 查询的优化

1.根据查询条件建立合适的index

2.因为SQL是从右向左解析,多表查询时,记录数少的表放在右边

3.多个条件时,收敛快的条件放在右边。

4.避免使用复杂的集合函数,象not in等。

5.避免在条件中对字段进行函数操作

6.尽量避免使用select *,应该写出需要查询的字段

7.java中尽量使用preparestatement执行sql,从而共享执行计划"

9. 怎么看执行计划

使用explain或者autotrace查看执行计划

10. 如何强制一个SQL语句使用索引? 使用index hints

11. Oracle中的PL/SQL块是否熟悉?Oracle中的内置函数是否熟悉?

内置函数:ASCIICHRCONCAT, decode,to_date,to_char,to_number等等。

12. 如何取一个没有排序的查询结果中的前10条记录?

select fielda from tablea where rownum<=10;

13. 问:如何取一个有排序的查询结果中的前10条记录?

select fielda from  (select fielda from tablea order by fieldb ) where rownum<=10;

错误写法:select fielda from tablea where rownum<=10 order by fieldb;

14. 如何取一个没有排序的查询结果中的第11条到第20条记录?

select fielda from 

(select fielda,rownum rn from tablea where rownum<=20) 

where rn>=11;

15. 如何取一个有排序的查询结果中的第11条到第20条记录?

select fielda from (select fielda ,rownum rn from (select fielda from tablea order by fieldb ) 

where rownum<=20) where rn>=11;

16. 数据库设计中,主键的作用?

主键的作用保持数据表记录的唯一性,建立主键索引和作为外键使用.使用主键与外键的配对来表示实体间的连接.

17. Oracle数据库设计中,建立外键的方法?

1)用Create table命令语句在设计数据库表时建立外键

Create table Depart (

DepNO Number(2), 

DepName varchar2(10), 

CONSTRAINT pk_dept PRIMARY KEY (DepNO)

);

Create table Emp (

EmpNo Number(4), 

EmpName varchar2(20), 

DepNo  CONSTRAINT fk_deptno References Depart(DepNo)

);

2)用Alter table命令语句,为一个存在的表添加外键

Create table Depart (

DepNO Number(2), 

DepName varchar2(10), 

CONSTRAINT pk_dept PRIMARY  KEY (DepNO)

);

Create table Emp( 

EmpNo Number(4), 

EmpName varchar2(20), 

DepNo Number(2)

);

Alter table Emp  

ADD  CONSTRAINT  fk_deptno  Foreign   key(DepNo)  References Depart(DepNo);

18. oracle中的常用函数,如:日期函数

1. 日期函数

       ADD_MONTHS:返回给指定的日期加上指定的月数后的日期。其格式为add_months(d,n) , 其中d是日期,n表示月数。

       MONTHS_BETWEEN:返回两个日期之间的月数。其格式为:months_between(d1,d2) , d1晚于d2,结果返回正数,否则返回负数。

       LAST_DAY:返回指定日期当月的最后一天的日期值。格式为:last_day(d)

       ROUND:返回日期值,此日期四舍五入为格式模型指定的单位。格式为:round(d,[fmt])

       NEXT_DAY:返回指定的下一个星期几的日期,格式为:next_day(d,day)

       TRUNC:将指定日期截断为由格式模型指定的单位的日期,与round函数不同的是它只舍不入。 格式为:trunc(d,[fmt]),如果不指定fmt,日期则被截断为天。

       EXTRACT:提取日期时间类型中的特定部分。 格式为:extract(fmt from d)。注意:此处的格式不用使用单引号。

2. 字符函数

       INITCAP(char) :将首字母转换为大写。

       LOWER(char) : 转换为小写

       UPPER(char) :  转换为大写

       LTRIM(char,set) :左剪裁

       RTRIM(char,set) :右剪裁

       TRANSLATE(char,from):按字符翻译

       REPLACE(char,search_str,replace_str): 字符串替换

       INSTR(char,substr[,pos]) :查找子串位置

       SUBSTR(char,pos,len) : 取子字符串

       CONCAT(char1,char2) : 连接字符串

       CHR:根据提供的ASCII码返回对应的字符

       LPADRPAD: 左填充和右填充

       LENGTH:返回字符串的长度

       DECODE:与执行逐个字符替换的translate函数不同的是,decode函数进行逐个值的替换。

3. 数字函数

       ABS(n) : 取绝对值                 SIGN(n) :  取符号

       CEIL(n) : 向上取整                FLOOR(n) : 向下取整

       SIN(n) : 正弦                     FOWER(m,n): mn次幂

       COS(n) : 余弦                     MOD(m,n): 取余数

       ROUND(m,n): 四舍五入              TRUNC(m,n): 截断                      

       SQRT(n): 平方根

4. 转换函数

       TO_CHAR

       TO_DATE

       TO_NUMBER

5. 其他函数

       NVL(expre1,expre2) : 将空值替换为指定的值

       NVL2(expre1,expre2,expre3): expre1不是空值,NVL2返回expre2,否则返回expre3

       NULLIF(expre1,expre2) : 比较两个表达式,如果相等,返回空值,否则返回expre1

6. 分组函数

       AVG

       MIN :参数列中所有值的最小值

       MAX

       SUM

       COUNT

7. 分析函数

       ROW_NUMBERRANKDENSE_RANK

[数据库简单SQL语句总结 

1.在查询结果中显示列名:

a.as关键字:select name as '姓名'   from students order by age
b.直接表示:select name '姓名'   from students order by age

2.精确查找:

a.in限定范围:select * from students where native in ('湖南', '四川') 
b.between...andselect * from students where age between 20 and 30
c.“=”select * from students where name = '李山
d.like:select * from students where name  like  '%' (注意查询条件中有“%”,则说明是部分匹配,而且还有先后信息在里面,即查找以开头的匹配项。所以若查询有的所有对象,应该命令:'%%';若是第二个字为李,则应为'_%''_''__')
e.[]匹配检查符:select * from courses where cno like '[AC]%' (表示或的关系,与"in(...)"类似,而且"[]"可以表示范围,如:select * from courses where cno like '[A-C]%')

3.对于时间类型变量的处理

a.smalldatetime直接按照字符串处理的方式进行处理,例如:
 select * from students where birth > = '1980-1-1'  and birth <= '1980-12-31' 

4.集合函数

a.count()求和,如:select count(*)  from students (求学生总人数)
b.avg()求平均,如:select avg(mark)  from grades where cno=’B2’
c.max()min()求最大与最小

5.分组group

常用于统计时,如分组查总数:select gender,count(sno)  from students group by gender
(查看男女学生各有多少)  注意:从哪种角度分组就从哪列"group by"
对于多重分组,只需将分组规则罗列。比如查询各届各专业的男女同学人数 ,那么分组规则有:届别(grade)、专业(mno)和性别(gender),所以有"group by grade, mno, gender"
select grade, mno, gender, count(*)  from students group by grade, mno, gender
通常group还和having联用,比如查询1门课以上不及格的学生,则按学号(sno)分类有:
select sno,count(*) from grades  where mark<60  group by sno  having count(*)>1 

6.UNION联合

合并查询结果,如:SELECT * FROM students
WHERE name like ‘%’  UNION [ALL]  SELECT * FROM students  WHERE name like ‘%’

7.多表查询

a.内连接

select g.sno,s.name,c.coursename   from grades g JOIN students s ON g.sno=s.sno  JOIN courses c ON  g.cno=c.cno
(注意可以引用别名)

b.外连接

b1.左连接

select courses.cno,max(coursename),count(sno)  from courses LEFT JOIN grades ON courses.cno=grades.cno  group by courses.cno
左连接特点:显示全部左边表中的所有项目,即使其中有些项中的数据未填写完全。左外连接返回那些存在于左表而右表中却没有的行,再加上内连接的行。

b2.右连接

与左连接类似

b3.全连接

select sno,name,major  from students FULL JOIN majors ON students.mno=majors.mno
两边表中的内容全部显示

c.自身连接 

select c1.cno,c1.coursename,c1.pno,c2.coursename  from courses c1,courses c2  where c1.pno=c2.cno
采用别名解决问题。

d.交叉连接

select lastname+firstname from lastname CROSS JOIN firstanme
相当于做笛卡儿积

8.嵌套查询

a.用关键字IN,如查询李山的同乡:

select  *  from students  where  native  in  (select native from students where name=’ 李山’) 

b.使用关键字EXIST,比如,下面两句是等价的:

select * from students  where sno in (select sno from grades where cno=’B2’)  

select * from students where exists  (select * from grades where  grades.sno=students.sno AND cno=’B2’)

 

9.关于排序order

a.对于排序order,有两种方法:asc升序和desc降序

b.对于排序order,可以按照查询条件中的某项排列,而且这项可用数字表示,如:

select sno,count(*) ,avg(mark) from grades   group by sno  having avg(mark)>85  order by 3 

10.其他

a.对于有空格的识别名称,应该用"[]"括住。

b.对于某列中没有数据的特定查询可以用null判断,如select sno,courseno from grades where mark IS NULL

c.注意区分在嵌套查询中使用的anyall的区别,any相当于逻辑运算“||”all则相当于逻辑运算“&&”

d.注意在做否定意义的查询是小心进入陷阱:
如,没有选修‘B2’课程的学生 :
select students.*  from students, grades where students.sno=grades.sno  AND grades.cno <> ’B2’                  
上面的查询方式是错误的,正确方式见下方:
select * from students where not exists  (select * from grades  where grades.sno=students.sno AND cno='B2') 

11.关于有难度多重嵌套查询的解决思想:
如,选修了全部课程的学生:
select * from students where not exists ( select *  from courses  where NOT EXISTS 
    (select *  from grades where sno=students.sno  AND cno=courses.cno))
最外一重:从学生表中选,排除那些有课没选的。用not exist。由于讨论对象是课程,所以第二重查询从course表中找,排除那些选了课的即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值