Chapter 5 Advanced SQL

高级SQL(Chapter 5)

使用其他语言调用SQL

动态SQL

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

JDBC(for Java)5.1.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注入),预备语句是首选

预备语句.png
  • 可更新结果集

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

  • 事务

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


conn.setAutoCommit(false/true);

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


conn.commit();

conn.rollbacck();

  • 其他

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

getClob();

setBlob();

ODBC(for C, C++)5.1.2

ODBC Example

嵌入式SQL5.1.3

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

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

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


EXEC SQL <嵌入式sql语句>

  • 连接到数据库

EXEC SQL connect to <server> user <user_name> using <password>;

  • 使用宿主语言变量

变量声明要这样放


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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,312评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,578评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,337评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,134评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,161评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,303评论 1 280
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,761评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,421评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,609评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,450评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,504评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,194评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,760评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,836评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,066评论 1 257
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,612评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,178评论 2 341

推荐阅读更多精彩内容