Chapter 5 Advanced SQL

高级SQL(Chapter 5)

使用其他语言调用SQL

动态SQL

运行时以字符串形式构建SQL查询→提交查询→把结果存入程序变量中

JDBC(for Java)5.1.1

Chapter 5 Advanced SQL_第1张图片
JDBC Example.png
  • 使用时,Java程序必须引用java.sql.*

  • 驱动程序的加载


Class.forName(String driver);

driver:一个实现了java.sql.Driver接口的实体类

  • 连接到数据库

Connection con=DriverManager.getConnection(String url, String userid, String passwd);

url:指明服务器所在的主机名称及端口等其他信息

  • 向数据库中传递SQL语句

Statement stmt=conn.createStatement();//创建statement

stmt.excuteUpdate(String expression);//实现非查询语句(更新,删除,插入等),以字符串形式作为参数。返回整数表达被操作的元组数

ResultSet rset=stmt.excuteQuery(String expression);//实现查询,返回结果集,存在ResultSet类型的对象rset中

  • 对结果集的操作

while(rset.next()){

    System.out.println(rset.getString("dept_name")+" "+rset.getFloat(2));

}

rset.next()查看集合中是否还剩下未取出的元组,有的话就取出,没有就返回false

getString和getFloat是把结果集中的东西转化成String或Float

参数“dept_name”表示提取属性名为dept_name的值

参数“2”表示提取第二个属性的值

  • 完成操作之后记得关闭

stmt.close();

conn.close();

  • 预备语句

感觉有点像模板函数一样,某些地方可以到时候再替换

除此以外,出于安全和规范考虑(防sql注入),预备语句是首选

Chapter 5 Advanced SQL_第2张图片
预备语句.png
  • 可更新结果集

对结果集中元组的更新将引起数据库中的更新

  • 事务

默认情况下每一句sql语句都被当成一个自动提交的事务,可以使用


conn.setAutoCommit(false/true);

打开或关闭这种自动提交,关闭之后通过以下方式进行显式提交或回滚


conn.commit();

conn.rollbacck();

  • 其他

getBlob();//返回的不是大对象本身,而是指针一样的东西

getClob();

setBlob();

ODBC(for C, C++)5.1.2

Chapter 5 Advanced SQL_第3张图片
ODBC Example

嵌入式SQL5.1.3

将SQL查询嵌入到其他语言(称为宿主语言)中,使用宿主语言写出的程序可以通过嵌入式sql的语法访问数据库

一个使用嵌入式sql的程序在编译前必须用特殊的预处理器进行处理

为了使预处理器识别嵌入式sql请求,使用如下语句


EXEC SQL <嵌入式sql语句>

  • 连接到数据库

EXEC SQL connect to  user  using ;

  • 使用宿主语言变量

变量声明要这样放


EXEC SQL BEGIN DECLARE SECTION;

int credit_amount;

EXEC SQL END DECLARE SECTION;

使用的时候要在前面加上冒号以区分sql变量和宿主变量

  • 声明游标

EXEC SQL

    declare c cursor for

    select Id,name

    from student

    where tot_credit>:credit_amount;//:credit_amount是宿主语言变量,所以前面加了个冒号

用open语句来执行查询,并把结果存放在临时关系中


EXEC SQL open c;

使用fetch语句把结果元组赋值给宿主语言的变量,要求一个变量对应一个属性


EXEC SQL fetch c into :si,:sn;

fetch语句每次只会取出一条结果,并将游标后移一个,所以可以通过循环取出所有结果

当结果已经被全部取出,SQLSTATE被置为“02000”,意味不再有数据

使用如下close语句删除临时关系


EXEC SQL close c;


函数和过程

声明和调用SQL函数

  • 格式

eg.给定一个系名,返回该系中的教师数目


create function dept_count (dept_name varchar(20))

    returns integer #声明返回的类型

    begin

    declare d_count integer;

        select count(*) into d_count

        from instructor

        where instructor.dept_name=dept_name#这里为什么不需要用dept_count.dept_name

    return d_count;

    end

  • 支持以关系为返回结果的函数,称为表函数(table functions)

eg.


create function instructor_of(dept_name varchar(20))

    returns table(

        ID varchar(5),

        name varchar(20),

        dept_name varchar(20),

        salary numeric(8,2))

    return table

        (select ID,name,dept_name,salary

        from instructor

        where instructor.dept_name=instructor_of.dept_name);#使用函数的参数时要用函数名instructor_of作为前缀  

  • 调用的时候直接用

声明和调用过程(procedure)


create proocedure dept_count(in dept_name varchar(20),out d_count integer)

    begin

        select count(*) into d_count

        from instructor

        where instructor.dept_name=dept_count.dept_name

    end

  • 调用的时候用call

declare d_count integer;

call dept_count('Physics',d_count);

其他语句

  • while语句

while 布尔条件 do

    语句序列;

end while

  • repeat语句

repeat

    语句序列;

until 布尔表达式

end repeat

  • for循环

declare n integer default 0;//默认值为0

for r as

    select budget from department

    where dept_name='music'

do 

    set n=n-r.budget

end for

//leave相当于break

//iterate相当于continue

  • if语句

if ...

    then ...

elseif ...

    then ...

else ...

end if

  • 异常条件(Exception)

declare out_of_classroom_seats condition

declare exit handler for out_of_classroom_seats

begin

......//这里的语句可以执行signal out_of_classroom_seats来引发异常

end

SQL中用其他语言定义函数

效率高,可跨数据库

  • Function

create fuction dept_count(dept_name varchar(20))

returns integer

language C

external name '/user/avi/bin/dept_count'

  • Procedure

create procedure dept_count_proc(in dept_name varchar(20),out count integer)

language C

external name '/user/avi/bin/dept_count_proc'


触发器(Trigger)

格式


delimiter @ #声明分隔符@

create trigger timeslot_check1 after insert on section

for each row #在插入的每一行上进行迭代

begin 

 if(NEW.time_slot_id #可以用OLD和NEW来表示操作发生前后的表

    NOT IN(

    SELECT 

         time_slot_id

    FROM

         time_slot))

 then 

  rollback;

 end if;

end @ #结束以@为分隔符的时光

delimiter ; #恢复以;作为分隔符的时光

设为无效


alter trigger ... disable;


高级聚集特性

排序


select ID, rank() over (order by(GPA) desc) as s_rank # rank函数对所有在order by属性上相等的元组赋予相同的名次

from student_grades

order by s_rank;

空值null的存在可能会影响排序,可以通过设定nulls first或nulls last指定


select ID, rank() over (order by GPA desc nulls first) as s_rank

你可能感兴趣的:(Chapter 5 Advanced SQL)