第一篇:课题:SQLServer存储过程返回值总结
SQLServer存储过程返回值总结
1.存储过程没有返回值的情况(即存储过程语句中没有return之类的语句)
用方法 int count = ExecuteNonQuery(..)执行存储过程其返回值只有两种情况
(1)假如通过查询分析器执行该存储过程,在显示栏中假如有影响的行数,则影响几行count就是几
(2)假如通过查询分析器执行该存储过程,在显示栏中假如显示'命令已成功完成。'则count =-1;在显示栏中假如有查询结果,则count =-1
总结:A.ExecuteNonQuery()该方法只返回影响的行数,假如没有影响行数,则该方法的返回值只能是-1,不会为0。
B.不论ExecuteNonQuery()方法是按照CommandType.StoredProcedure或者CommandType.Text执行,其效果和A一样。
2.获得存储过程的返回值--通过查询分析器获得
(1)不带任何参数的存储过程(存储过程语句中含有return)
---创建存储过程
CREATE PROCEDURE testReturn
AS
return 145
GO
---执行存储过程
DECLARE @RC int
exec @RC=testReturn
select @RC
---说明
查询结果为145
(2)带输入参数的存储过程(存储过程语句中含有return)
---创建存储过程
create procedure sp_add_table1
@in_name varchar(100), @in_addr varchar(100), @in_tel varchar(100)
as
if(@in_name = '' or @in_name is null)
return 1
else
begin
insert into table1(name,addr,tel)values(@in_name,@in_addr,@in_tel)
return 0
end
---执行存储过程
<1>执行下列,返回1
declare @count int exec @count = sp_add_table1 '','中三路','123456' select @count
<2>执行下列,返回0
declare @count int exec @count = sp_add_table1 '','中三路','123456' select @count
---说明
查询结果不是0就是1
(3)带输出参数的存储过程(存储过程中可以有return可以没有return)
例子A:
---创建存储过程
create procedure sp_output
@output int output
as
set @output = 121
return 1
---执行存储过程
<1>执行下列,返回121
declare @out int
exec sp_output @out output
select @out
<2>执行下列,返回1
declare @out int
declare @count int exec @count = sp_output @out output
select @count
---说明
有return,只要查询输出参数,则查询结果为输出参数在存储过程中最后变成的值;只要不查询输出参数,则查询结果为return返回的值
例子B:
---创建存储过程
create procedure sp_output
@output int output
as
set @output = 121
---执行存储过程
<1>执行下列,返回121
declare @out int
exec sp_output @out output
select @out
<2>执行下列,返回0
declare @out int
declare @count int
exec @count = sp_output @out output
select @count
---说明
没有return,只要查询输出参数,则查询结果为输出参数在存储过程中最后变成的值;只要不查询输出参数,则查询结果为0
总结:
(1)存储过程共分为3类:
A.返回记录集的存储过程---------------------------其执行结果是一个记录集,例如:从数据库中检索出符合某一个或几个条件的记录
B.返回数值的存储过程(也可以称为标量存储过程)-----其执行完以后返回一个值,例如:在数据库中执行一个有返回值的函数或命令
C.行为存储过程----用来实现数据库的某个功能,而没有返回值,例如:在数据库中的更新和删除操作
(2)含有return的存储过程其返回值为return返回的那个值
(3)没有return的存储过程,不论执行结果有无记录集,其返回值是0
(4)带输出参数的存储过程:假如有return则返回return返回的那个值,假如要select输出参数,则出现输出参数的值,于有无return无关
--------------------3.获得存储过程的返回值--通过程序获得
---------------------------SqlParameter[] cmdParms = {..,new SqlParameter(“@return”,SqlDbType.Int)};cmdParms[cmdParms.Length1].Direction = ParameterDirection.Output或者 cmdParms[cmdParms.Length1].Value;
分类: asp.net
第二篇:存储过程的优缺点个人总结
优点
1.在生产环境下,可以通过直接修改存储过程的方式修改业务逻辑(或bug),而不用重启服务器。但这一点便利被许多人滥用了。有人直接就在正式服务器上修改存储过程,而没有经过完整的测试,后果非常严重。
2.执行速度快。存储过程经过编译之后会比单独一条一条执行要快。但这个效率真是没太大影响。如果是要做大数据量的导入、同步,我们可以用其它手段。
3.减少网络传输。存储过程直接就在数据库服务器上跑,所有的数据访问都在服务器内部进行,不需要传输数据到其它终端。但我们的应付服务器通常与数据库是在同一内网,大数据的访问的瓶颈会是硬盘的速度,而不是网速。
4.能够解决presentation与数据之间的差异,说得文艺青年点就是解决OO模型与二维数据持久化之间的阻抗。领域模型和数据模型的设计可能不是同一个人(一个是SA,另一个是DBA),两者的分歧可能会很大——这不奇怪,一个是以OO的思想来设计,一个是结构化的数据来设计,大家互不妥协——你说为了软件的弹性必须这么设计,他说为了效率必须那样设计,为了抹平鸿沟,就用存储过程来做数据存储的逻辑映射(把属性映射到字段)。好吧,台下已经有同学在叨咕ORM了。
5.方便DBA优化。所有的SQL集中在一个地方,DBA会很高兴。这一点算是ORM的软肋。不过按照CQRS框架的思想,查询是用存储过程还是ORM,还真不是问题——DBA对数据库的优化,ORM一样会受益。况且放在ORM中还能用二级缓存,有些时候效率还会更高。
缺点
1.SQL本身是一种结构化查询语言,加上了一些控制(赋值、循环和异常处理等),但不是OO的,本质上还是过程化的,面对复杂的业务逻辑,过程化的处理会很吃力。这一点算致命伤。
2.不便于调试。基本上没有较好的调试器,很多时候是用print来调试,但用这种方法调试长达数百行的存储过程简直是噩梦。好吧,这一点不算啥,C#/java一样能写出噩梦般的代码。
3.没办法应用缓存。虽然有全局临时表之类的方法可以做缓存,但同样加重了数据库的负担。如果缓存并发严重,经常要加锁,那效率实在堪忧。
4.无法适应数据库的切割(水平或垂直切割)。数据库切割之后,存储过程并不清楚数据存储在哪个数据库中。
5.精通SQL的新手越来越少——不要笑,这是真的,我面试过N多新人,都不知道如何创建全局临时表、不知道having、不知道聚集索引和非聚集索引,更别提游标和提交叉表查询了。好吧,这个缺点算是凑数用的,作为屌丝程序员,我们的口号是:没有不会的,只有不用的。除了少数有语言洁癖的人,我相信精通SQL只是时间问题。
总结
存储过程最大的优点是部署的方便性——可以在生产环境下直接修改——虽然滥用的后果很严重。
存储过程最大的缺点是SQL语言本身的局限性——我们不应该用存储过程处理复杂的业务逻辑——让SQL回归它“结构化查询语言”的功用吧。
第三篇:mysql 5.0存储过程学习总结
mysql 5.0存储过程学习总结
一.创建存储过程 1.基本语法:
create procedure sp_name()begin end 2.参数传递
二.调用存储过程
1.基本语法:call sp_name()注意:存储过程名称后面必须加括号,哪怕该存储过程没有参数传递
三.删除存储过程 1.基本语法:
drop procedure sp_name// 2.注意事项
(1)不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程
四.区块,条件,循环 1.区块定义,常用 begin end;也可以给区块起别名,如: lable:begin end lable;可以用leave lable;跳出区块,执行区块以后的代码
2.条件语句 3.循环语句 :while循环 loop循环 repeat until循环 repeat until循环
五.其他常用命令
1.show procedure status 显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等 2.show create procedure sp_name 显示某一个存储过程的详细信息
mysql存储过程基本函数
一.字符串类
CHARSET(str)//返回字串字符集 CONCAT(string2 [,...])//连接字串
INSTR(string ,substring)//返回substring首次在string中出现的位置,不存在返回0 LCASE(string2)//转换成小写
LEFT(string2 ,length)//从string2中的左边起取length个字符 LENGTH(string)//string长度
一起推论坛
一起推论坛www.feisuxs
第四篇:用java调用oracle存储过程总结
用java调用oracle存储过程总结
分类: PL/SQL系列 202_-09-24 15:08 253人阅读 评论(0)收藏 举报
声明:
以下的例子不一定正确,只是为了演示大概的流程。
一:无返回值的存储过程 存储过程为:
CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2)AS BEGIN
INSERT INTO HYQ.B_ID(I_ID,I_NAME)VALUES(PARA1, PARA2);END TESTA;
然后呢,在java里调用时就用下面的代码: package com.hyq.src;
import java.sql.*;import java.sql.ResultSet;
public class TestProcedureOne {
public TestProcedureOne(){
}
public static void main(String[] args){
String driver = “oracle.jdbc.driver.OracleDriver”;
String strUrl = “jdbc:oracle:thin:@127.0.0.1:1521: hyq ”;
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
CallableStatement cstmt = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, “ hyq ”, “ hyq ”);
CallableStatement proc = null;
proc = conn.prepareCall(“{ call HYQ.TESTA(?,?)}”);
proc.setString(1, “100”);
proc.setString(2, “TestOne”);
proc.execute();
}
catch(SQLException ex2){
ex2.printStackTrace();
}
catch(Exception ex2){
ex2.printStackTrace();
}
finally{
try {
if(rs!= null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch(SQLException ex1){
}
}
} }
二:有返回值的存储过程(非列表)
当然了,这就先要求要建张表TESTTB,里面两个字段(I_ID,I_NAME)。
存储过程为: CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2)AS BEGIN
SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;END TESTB;
在java里调用时就用下面的代码: package com.hyq.src;
public class TestProcedureTWO {
public TestProcedureTWO(){
}
public static void main(String[] args){
String driver = “oracle.jdbc.driver.OracleDriver”;
String strUrl = “jdbc:oracle:thin:@127.0.0.1:1521:hyq”;
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, “ hyq ”, “ hyq ”);
CallableStatement proc = null;
proc = conn.prepareCall(“{ call HYQ.TESTB(?,?)}”);
proc.setString(1, “100”);
proc.registerOutParameter(2, Types.VARCHAR);
proc.execute();
String testPrint = proc.getString(2);
System.out.println(“=testPrint=is=”+testPrint);
}
catch(SQLException ex2){
ex2.printStackTrace();
}
catch(Exception ex2){
ex2.printStackTrace();
}
finally{
try {
if(rs!= null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch(SQLException ex1){
}
}
} }
}
注意,这里的proc.getString(2)中的数值2并非任意的,而是和存储过程中的out列对应的,如果out是在第一个位置,那就是proc.getString(1),如果是第三个位置,就是proc.getString(3),当然也可以同时有多个返回值,那就是再多加几个out参数了。
三:返回列表
由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了.所以要分两部分,1,建一个程序包。如下:
CREATE OR REPLACE PACKAGE TESTPACKAGE AS
TYPE Test_CURSOR IS REF CURSOR;end TESTPACKAGE;
2,建立存储过程,存储过程为:
CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR)IS BEGIN
OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;END TESTC;
可以看到,它是把游标(可以理解为一个指针),作为一个out 参数来返回值的。在java里调用时就用下面的代码: package com.hyq.src;import java.sql.*;
import java.io.OutputStream;import java.io.Writer;
import java.sql.PreparedStatement;import java.sql.ResultSet;import oracle.jdbc.driver.*;
public class TestProcedureTHREE {
public TestProcedureTHREE(){
}
public static void main(String[] args){
String driver = “oracle.jdbc.driver.OracleDriver”;
String strUrl = “jdbc:oracle:thin:@127.0.0.1:1521:hyq”;
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(strUrl, “hyq”, “hyq”);
CallableStatement proc = null;
proc = conn.prepareCall(“{ call hyq.testc(?)}”);
proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
rs =(ResultSet)proc.getObject(1);
while(rs.next())
{
System.out.println(“
}
}
catch(SQLException ex2){
ex2.printStackTrace();
}
catch(Exception ex2){
ex2.printStackTrace();
}
finally{
try {
if(rs!= null){
rs.close();
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
catch(SQLException ex1){
}
}
} }
四。Hibernate调用存储过程
Connection con = session.connect();
CallableStatement proc = null;
con = connectionPool.getConnection();
proc = con.prepareCall(“{ call set_death_age(?, ?)}”);proc.setString(1, XXX);
proc.setInt(2, XXx);...proc.execute();
session.close();
在Hibernate中调用存储过程的示范代码--
如果底层数据库(如Oracle)支持存储过程,也可以通过存储过程来执行批量更新。存储过程直接在数据库中运行,速度更加快。在Oracle数据库中可以定义一个名为batchUpdateStudent()的存储过程,代码如下:
create or replace procedure batchUpdateStudent(p_age in number)as begin update STUDENT set AGE=AGE+1 where AGE>p_age;end;以上存储过程有一个参数p_age,代表学生的年龄,应用程序可按照以下方式调用存储过程: tx = session.beginTransaction();Connection con=session.connection();String procedure = “{call batchUpdateStudent(?)}”;CallableStatement cstmt = con.prepareCall(procedure);cstmt.setInt(1,0);//把年龄参数设为0 cstmt.executeUpdate();tx.commit();在以上代码中,我用的是Hibernate的 Transaction接口来声明事务,而不是采用JDBC API来声明事务。
存储过程中有一个参数p_age,代表客户的年龄,应用程序可按照以下方式调用存储过程:
代码内容
tx = session.beginTransaction();Connection con=session.connection();
String procedure = “{call batchUpdateCustomer(?)}”;
CallableStatement cstmt = con.prepareCall(procedure);
cstmt.setInt(1,0);//把年龄参数设为0
cstmt.executeUpdate();
tx.commit();
CREATE procedure selectAllUsers DYNAMIC RESULT SETS 1 BEGIN
DECLARE temp_cursor1 CURSOR WITH RETURN TO CLIENT FOR
SELECT * FROM test;
OPEN temp_cursor1;END;
映射文件中关于存储过程内容如下
............
{ ? = call selectAllUsers()}
{ ? = call selectAllUsers()} 也可以写成{ call selectAllUsers()},如果有参数就写成
{ ? = call selectAllUsers(?,?,?)}
代码中对query设置相应位置上的值就OK Java调用关键代码如下
Session session = HibernateUtil.currentSession();
Query query = session.getNamedQuery(“selectAllUsers”);
List list = query.list();
System.out.println(list);
要求你的存储过程必须能返回记录集,否则要出错
如果你的存储过程是完成非查询任务就应该在配置文件用以下三个标签
setFirstResult(int)和setMaxResults(int)方法来分页
第五篇:informix存储过程
INFORMIX数据库存储过程编写讲义
一、存储过程概念
sql语句执行的时候要先编译,然后执行。存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中。用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
二、标准语法格式
1、创建带参数存储过程
Create PROCEDURE “npmuser”.sp_sx_sum_ctr_traf_proc(tch_datetime datetime year to second , i_time integer)returning varchar(40);
--作 者:--创建时间:
--功能简述:统计农村话务量,改过程需要配置在服务器上,每个小时定时执行--提取一个小时的话务量并按所属行政区域分组(农村、城市、县城)--参数描述:tch_datetime 传入时间,i 提取传入时间前i个小时的数据--引用到的其他存储过程或函数:--被以下存储过程引用过:--修改历史:--修 改 人:--修改时间:--修改原因:
select first_result,parent_ne_id,ne_id,related_bsc,related_msc, region_id,province_id from tcc_ne_snap a where a.first_result = tch_datetime and a.ne_type = 300 and confirmed not in(2,5)and resource_status =1 into temp te_ne_snap。。。。。
return 'te_result';end PROCEDURE
2、创建不带参数存储过程
Create PROCEDURE “npmuser”.sp_sx_sum_ctr_traf_proc()returning varchar(40);
define TchDatetime datetime year to second;define snap_date datetime year to second;define Schema_id integer。。。。。
return 'te_result';end PROCEDURE
3、临时表
第一种方法,先建立临时表,再向临时表插入数据。Create temp te_table(col varchar(100));Insert into …
第二种方法,直接利用查询结果创建临时表。注意查询结果的列必须有列名。Select col_a,col_b,col_c From table Into temp te_table;
4、变量赋值
let snap_date = extend(extend(TchDatetime, year to day),year to second);let Schema_id =-1121449820;
5、调用及删除存储过程
Execute procedure sp_sx_sum_ctr_traf_proc();调用 drop procedure sp_sx_sum_ctr_traf_proc();删除 存储过程可以互相调用。
6、游标
游标是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。
foreach select ne_id,c into v_neid,v_c from te_radio_ne where region_name =v_region_name order by c desc--拥塞率大于5 if v_c > 5 then let v_id_1= v_id_1+1;update te_radio_ne set i_flag = 1 where ne_id= v_neid;--更新row_id列 update te_radio_ne set row_id = v_id_1 where ne_id= v_neid;end if let v_neid = 0;let v_c = 0;end foreach;2
三、网管三期报表实例讲解
1、农村话务量报表
sp_sx_sum_ctr_traf_proc.TXT
2、统计市区基站整体指标(c1)报表
sp_sx_sum_traf_proc.txtsp_sx_traffic_proc.TXT
3、按地市提取TOPN小区退服总时长及平均时长
sp_sx_drop_site_topn_proc.TXTsp_sx_get_topn.TXT
四、特殊的存储过程
1、函数
INFORMIX中存储过程与函数的区分界限十分模糊。而在其他数据库中,函数(FUNCTION)的建立语法与存储过程区分明显。函数实际上是抽象出一部分使用比较频繁,通用性比较强的存储过程来被其他过程所调用。
实例: 除法函数
create procedure “npmuser”.sfb_pfloat_1(a float, b float, ret0 float default 0.00, ret1 float default-1.00)returning float;define res float;if b = 0 and a = 0 then return ret0;end if;if b = 0 and a<>0 then return ret1;end if;let res = a/b;return res;end procedure;提取网元名称函数
create procedure “npmuser”.soa_get_nename(id int, type int)returning varchar(64,0);define nename varchar(64,0);define usname varchar(64,0);define zhname varchar(64,0);define cityname varchar(32,0);define provid int;define provname varchar(32,0);define type_flag integer;let provid=-1;select distinct province_id into provid from system_setup;if provid is null or provid=-1 then return “unknown province”;end if;select userlabel into provname from tic_ne_def where ne_type = 10000 and ne_id = provid;if provname is null then let provname=“no name”;end if;if type = 10000 then let nename=provname[1,4];return nename;end if;select distinct zh_label,userlabel into zhname,usname from tcc_ne_frame where ne_type = type and ne_id = id and province_id=provid;if(zhname is null)or(zhname = “")then let nename=usname;else let nename=zhname;end if;if nename is null then let nename = ”no_name“;end if;if(type = 10004 or type = 10003)then let nename = provname[1,4] || ”-“ || nename;return nename;end if;select count(*)into type_flag
from tia_type_def where type_id = type;if(type_flag = 0)then let nename=”unknown type";end if;return nename;end procedure;
2、触发器
触发器是在特定条件下执行的特殊的存储过程。特定条件指触发器所依附的表,发生插入、删除、修改等事件时。
其中INSERT是一个触发器事件,表中插入行时触发器被激活,一个表只有一个INSERT触发器,DELETE是一个触发器事件,表中删除行时触发器被激活,一个表只有一个DELETE触发器。UPDATE是一个触发器事件,表中根性列时触发器被激活,如果包括列清单,则更新列清单中的列时触发器被激活。否则更形表中任何列时触发器被激活,一个表可以有多个UPDATE触发器。但是列清单要相互排斥。
触发器包含两种二维数组或者说两条行记录。一种为旧数据(OLD),表示被删除的数据,或者被更新前数据。一种为新数据(NEW),表示新增数据,或更新后数据。
实例: 删除触发器
create trigger tg_delete_dc_bsc_info delete on dc_bsc_info referencing old as a for each row(delete from dc_bsc_info_his where start_time = a.start_time and int_id = a.int_id and compress_date = a.compress_date),(insert into dc_bsc_info_his values(a.insert_time ,a.start_time ,a.stop_time ,a.fill_time ,a.ne_class,a.ne_name,a.int_id ,a.city_id ,a.sdchh_avail_carrie ,a.sdcch_traffic ,a.sdcch_call_att ,a.sdchh_assi_fail_num ,a.sdchh_call_drop ,a.sdchh_call_block ,a.tch_avail_carrier ,a.tch_traffic ,a.tch_att_num ,a.tch_overflow_num ,a.tch_assi_failed_num ,a.tch_unsuc_num ,a.tch_seize_num ,a.tch_call_att ,a.tch_call_block ,a.tch_failed_assi ,a.tch_call_seize ,a.tch_call_drop ,a.gsm1800_traf ,a.ho_req ,a.ho_succs ,a.worst_cell ,a.avail_cell ,a.acc_cell ,a.sdcch_seize_att ,a.tch_unsuc_call ,a.att_sdcch_seiz ,a.flag ,a.compress_date ,a.vendor_id));新增触发器
create trigger tg_insert_dc_bsc_info insert on dc_bsc_info referencing new as a for each row(delete from dc_bsc_info_bak where start_time = a.start_time and int_id = a.int_id and compress_date = a.compress_date),(insert into dc_bsc_info_bak values(a.insert_time ,a.start_time ,a.stop_time ,a.fill_time ,a.ne_class,a.ne_name,a.int_id ,a.city_id ,a.sdchh_avail_carrie ,a.sdcch_traffic ,a.sdcch_call_att ,a.sdchh_assi_fail_num ,a.sdchh_call_drop ,a.sdchh_call_block ,a.tch_avail_carrier ,a.tch_traffic ,a.tch_att_num ,a.tch_overflow_num ,a.tch_assi_failed_num ,a.tch_unsuc_num ,a.tch_seize_num ,a.tch_call_att ,a.tch_call_block ,a.tch_failed_assi ,a.tch_call_seize ,a.tch_call_drop ,a.gsm1800_traf ,a.ho_req ,a.ho_succs ,a.worst_cell ,a.avail_cell ,a.acc_cell ,a.sdcch_seize_att ,a.tch_unsuc_call ,a.att_sdcch_seiz ,a.flag ,a.compress_date ,a.vendor_id));更新触发器
create trigger tg_update_alarm update of alarm_state on alarm referencing new as a old as b for each row when(a.alarm_state>0)(INSERT INTO LucentSDH_WG_ALARM values(a.alarm_number,a.node_name,a.fault_location,a.a1_time,'', a.alarm_state,a.fault_type,current,0));
五、其他(关于连接的各种用法)
表test1、表test2结构: test1: test2: node1 property1 node2 property2 1100 a 1100 e 1200 a 1200 b 1300 b 1300 a 1400 d 1500 f
1、内连接 select * from test1 a,test2 b where a.node1=b.node2 结果集: 1100 a 1100 e 1200 a 1200 b 1300 b 1300 a
2、左连接
select * from test1 a left join test2 b on a.node1=b.node2 结果集: 1100 a 1100 e 1200 a 1200 b 1300 b 1300 a 1400 d
3、表a左连接表b,且表b加条件
结果集:表b的条件有效且左连接失效(相当于内连接)select * from test1 a left join test2 b on a.node1=b.node2 where b.property2<>'a' 结果集: 1100 a 1100 e 1200 a 1200 b
4、表a外连接表b,且表b加条件 结果集:表b的条件有效且左连接有效 select * from test1 a,outer test2 b where b.property2<>'a' and a.node1=b.node2 结果集: 1100 a 1100 e 1200 a 1200 b 1300 b 1400 d
5、右连接
select * from test1 a right join test2 b on a.node1=b.node2 结果集:
test2 test1 1100 e 1100 a 1200 b 1200 a 1300 a 1300 b 1500 f
6、表a右连接表b,且表a有条件 结果集:表a条件有效且右连接失效 select * from test1 a right join test2 b on a.node1=b.node2 where a.property1<>'a' 结果集: 1300 a 1300 b
7、表b外连接等价于表a右连接表b,且表a有条件 结果集:表a条件有效且右连接有 select * from test2 b,outer test1 a where a.property1<>'a' 7 and a.node1=b.node2 结果集:
test2 test1 1100 e 1200 b 1300 a 1300 b 1500 f
8、表a右连接表b,且表b有条件 结果集:表b条件有效且右连接有效 select * from test1 a right join test2 b on a.node1=b.node2 where b.property2<>'a' 结果集: 1100 e 1100 a 1200 b 1200 a 1500 f
9、全外连接
Select * From test1 a full outer join test2 b on a.node1 = b.node2 结果集:
1100 a 1100 e 1200 a 1200 b 1300 b 1300 a 1400 d 1500 f
10、自连接、交叉(无限制)连接(笛卡尔乘积)
自身连接是指同一个表自己与自己进行连接。这种一元连接通常用于从自反关系(也称作递归关系)中抽取数据。例如人力资源数据库中雇员与老板的关系。
Select * from test1 a,test1 b 交叉连接用于对两个源表进行纯关系代数的乘运算。它不使用连接条件来限制结果集合,而是将分别来自两个数据源中的行以所有可能的方式进行组合。数据集合中一的每个行都要与数据集合二中的每一个行分别组成一个新的行。例如,如果第一个数据源中有5个行,而第二个数据源中有4个行,那么在它们之间进行交叉连接就会产生20个行。人们将这种类型的结果集称为笛卡尔乘积。
大多数交叉连接都是由于错误操作而造成的;但是它们却非常适合向数据库中填充例子数据,或者预先创建一些空行以便为程序执行期间所要填充的数据保留空间。
select * from test1 a cross join test2 b 在交叉连接中没有on条件子句