执行存储过程

执行存储过程
执行存储过程

12.3.3 执行存储过程

当需要执行存储过程时,可使用EXECUTE或EXEC 语句。如果存储过程是批处理中的第一条语句,那么不使用EXECUTE 或EXEC关键字也可以执行该存储过程。

如果存储过程编写为可以接受参数值,那么可以提供参数值。

任务12.4

问题描述:执行任务12.3创建的存储过程Insertproduct,向产品表中追加一行。

解决方案1:

EXEC Insertproduct 8,'Konbu', '2 kg box', 24,6.0000, 5,10,0

解决方案2:

EXEC Insertproduct 8,'Konbu', '2 kg box', 24,6.0000, 5,10

解决方案3:

EXEC Insertproduct default,'Konbu', '2 kg box', 24,6.0000, 5,10

解决方案4:

EXEC Insertproduct @ProductName='Konbu',@QuantityPerUnit='2 kg box',

@UnitsInStock=24,@UnitPrice=6.0000,@UnitsOnOrder=5,@ReorderLevel=10

解决方案5:

EXEC Insertproduct @ReorderLevel=10, @UnitsOnOrder=5,

@UnitsInStock=24,@UnitPrice=6.0000, @QuantityPerUnit='2 kg

box',@ProductName='Konbu'

分析与讨论:

1.如果存储过程含有参数,则在执行存储过程时,必须为这些参数提供值(具有默认值的参数可以不提供值),而且提供的值必须是确定的值,例如方案1。并且必须按照CREATE PROCEDURE 语句中存储过程参数给出的顺序提供参数值,以下语句就会发生错误,因为不是按照顺序提供参数值。

EXEC Insertproduct 'Konbu',8,'2 kg box', 24,6.0000, 5,10,0

2.如果存储过程含有默认值参数,则在执行存储过程时,可省略为默认值参数提供值,但其它参数的值不能够省略,必须为这些参数提供值。例如方案2,没有为@Discontinued 参数提供值,则在执行存储过程时该参数的值为其默认值1.

3.虽然可以省略已提供默认值的参数,但只能截断参数列表。例如,如果一个存储过程有八个参数,可以省略第七个和第八个参数,但不能跳过第七个参数而仍然包含第八个参数,除非以@parameter = value 形式提供参数(参见4)。例如,方案2中,@CategoryID参数尽管是有默认值的参数,但由于它是第一个参数,而存储过程第二个参数必须提供值,因此执行存储过程时要为@CategoryID参数提供值,不能省略。如果要使用默认值作为参数的值,则可以使用DEFAULT关键字,例如方案3。

如果在存储过程中定义了参数的默认值,那么下列情况下将使用默认值:

1)执行存储过程时未指定参数值。

2)将DEFAULT 关键字指定为参数值。

4. 执行存储过程时,既可以通过提供在CREATE PROCEDURE 语句中给定的参数值(如解决方案1,解决方案2),来向存储过程参数传递值。也可以通过显式指定参数名称并分配适当的值(使用@parameter = value 的形式),来给存储过程参数传递值。

如果使用@parameter = value 的形式,那么可以按任意顺序提供参数,还可以省略那些已提供默认值的所有参数。注意,如果以@parameter = value 形式提供了一个参数,就必须按此种形式提供后面所有的参数。例如解决方案4和解决方案5,执行存储过程时存储过程@ProductName参数的值为'Konbu',@QuantityPerUnit参数的值为'2 kg box', @UnitsInStock参数的值为24,@UnitPrice参数的值为6.0000,@UnitsOnOrder参数的值为

5,@ReorderLevel参数的值为10,没有提供@CategoryID和@Discontinued参数的值,它们的值为其默认值。

执行存储过程时,如果参数名称和存储过程的参数名称不匹配,则这些参数都不会被接受。例如以下代码参数名称@ReorderLevelA和存储过程的参数名称不匹配,则参数@ReorderLevelA不会被接受。

EXEC Insertproduct @ReorderLevelA=10, @UnitsOnOrder=5,

@UnitsInStock=24,@UnitPrice=6.0000, @QuantityPerUnit='2 kg

box',@ProductName='Konbu'

执行存储过程时,服务器将拒绝所有未包含在存储过程创建期间的参数列表中的参数。

注意,在执行存储过程时指定参数名称允许按任意顺序提供参数值。如果未指定参数名称,则必须按照参数在存储过程中定义时的顺序(从左至右)来提供参数值(按照位置传递参数值),并且,如果给某一参数提供了值,则该参数前面的所有参数必须为它们提供值,即使这些参数有默认值(如方案2)。

12.4.1 使用变量、IF语句和RETURN语句

变量用来存储程序在运行过程中可以使用的值,用户可以定义变量,用户定义的变量称为局部变量。

IF语句根据表达式的值选择要执行的语句。IF语句的一般表示形式为:

IF (表达式)

BEGIN

语句块;

END

IF语句的执行方式如下:如果表达式的值为TRUE,则执行语句块,否则语句块不会被执行。语句块可为一条或多条语句,如果句块可为一条语句,可省略BEGIN、END。

任务12.6

问题描述:创建一个存储过程,用参数指定的产品类别ID的值查询该类的所有产品,并测试错误,如果存储过程成功执行,则存储过程返回0,如果执行存储过程时,执行存储过程中的SQL 语句发生错误,则存储过程返回返回错误号。并创建代码测试该程序过程。

解决方案:

1)创建ProductsByCategory1存储过程

CREATE Procedure ProductsByCategory1

(

@CategoryID int

)

AS

DECLARE @ErrorSave int;

SET @ErrorSave = 0;

SELECT * FROM Products

WHERE CategoryID = @CategoryID

ORDER BY ProductName;

IF (@@ERROR <> 0)

BEGIN

SET @ErrorSave = @@ERROR;

END

RETURN @ErrorSave;

GO

2)创建测试代码

DECLARE @ReturnStatus int;

EXECUTE @ReturnStatus =ProductsByCategory1 1;

SELECT'Return code = ' + CAST(@ReturnStatus AS CHAR(10));

GO

分析与讨论:

1.声明变量。使用DECLARE 语句声明变量,其格式如下:

DECLARE 变量名数据类型和长度

变量名的第一个字符必须为一个@。声明变量后变量的值初始化为NULL。

变量不能是text、ntext或image 数据类型。

下面的语句创建了一个名为@ErrorSave的变量,该变量的数据类型为int,变量的值设置为NULL。

DECLARE @ErrorSave int;

若要声明多个局部变量,可在定义的第一个变量后使用一个逗号,然后指定下一个变量名称和数据类型。例如,此DECLARE 语句创建了三个名为@ProductName、@QuantityPerUnit e 和@ProductID的变量,并将每个变量都初始化为NULL:DECLARE @ProductName nvarchar(30), @QuantityPerUnit nvarchar(20),

@ProductID int;

变量的作用域就是可以引用该变量的SQL 语句的范围。变量的作用域从声明变量的地方开始到声明变量的批处理或存储过程的结尾。

2. 变量赋值。可使用SET 语句为变量赋值,例如,下面的语句将值0赋给变量@ErrorSave。其中,“=”为赋值运算符。

SET @ErrorSave = 0;

3.输出变量的值。可以使用SELECT语句变量的值。例如以下示例首先声明变量@ReturnStatus,然后执行存储过程,将存储过程ProductsByCategory1的返回值赋给@ReturnStatus变量,最后输出变量@ReturnStatus的值:

DECLARE @ReturnStatus int;

EXECUTE @ReturnStatus =ProductsByCategory1 1;

SELECT @ReturnStatus;

也可以使用SELECT语句输出表达式的值。例如:

SELECT'Return code = ' + CAST(@ReturnStatus AS CHAR(10));

如果使用SELECT输出多个变量或表达式的值,则变量或表达式之间用逗号分隔。例如:

SELECT @ProductName, @QuantityPerUnit, @ProductID;

SELECT 表达式1, 表达式2, 表达式2;

4. 使用@@ERROR。@@ERROR是系统函数,它用来检测它的上一条SQL 语句是否执行成功,如果上一条SQL 语句执行成功,则@@ERROR 系统函数返回0;如果上一条SQL 语句语句生成错误,@@ERROR 将返回错误号。

@@ERROR 通常用于检测存储过程是成功还是失败。整数变量(如@ErrorSave)被初始化为0。在每个SQL 语句完成之后,立即测试@@ERROR 是否为0,如果不是0,将@@ERROR 保存到整数变量中。然后,存储过程将在RETURN 语句中返回变量。如果过程中的SQL 语句都没有错误,变量将保持为0。如果一个或多个语句生成错误,变量将包含最后一个错误号。

5. IF 语句。如果IF 语句中条件表达式的值为TRUE ,则执行IF 语句后的语句或语句块。如果IF 语句中条件表达式的值为FALSE ,则跳过IF 语句后的语句或语句块。

例如,在以上存储过程中,如果@@ERROR的值为0,则条件表达式@@ERROR <> 0的值为FALSE,这时不执行SET @ErrorSave = @@ERROR语句。如果@@ERROR的值不为0,则条件表达式@@ERROR <> 0的值TRUE,这时执行SET @ErrorSave = @@ERROR 语句。该语句将@@ERROR的值赋给变量@ErrorSave。

6. 使用BEGIN...END。BEGIN 和END用于定义语句块,它们可以用于定义一系列一起执行的SQL 语句。BEGIN 和END 语句必须成对使用,任何一个均不能单独使用。BEGIN 语句单独出现在一行中,后跟SQL 语句块。最后,END 语句单独出现在一行中,

指示语句块的结束。

BEGIN 和END 语句块必须至少包含一条SQL 语句。

7. RETURN语句。

RETURN 语句无条件从查询、存储过程或批处理中退出。RETURN 语句后面的语句都不执行。RETURN 语句的一般格式为:

RETURN integer_expression

其中integer_expression 为返回的整数值或整型表达式。

当在存储过程中使用RETURN 语句时,此语句可以指定返回给调用程序、批处理或过程的整数值。如果RETURN 未指定值,则存储过程返回0。

以上ProductsByCategory1存储过程中,当执行RETURN @ErrorSave语句时,退出存储过程,并将@ErrorSave作为存储过程的值返回。

8. SQL 语句中可包含存储过程返回的值,但必须以下列格式输入:

EXECUTE @return_status =

例如:

EXECUTE @ReturnStatus =ProductsByCategory1 1;

该语句执行存储过程,并将存储过程的返回值赋给变量@ReturnStatus。

MySql 数据库用java程序创建表以及存储过程

MySql 数据库用java程序创建表以及存储过程 1.同一般的数据库操作基本一样。 2.Statement.executeUpdate(String sql); 这个方法可以用来执行DDL语句,以及执行更新操作。 3.需要注意 CallableStatement 接口的用法。 用于执行 SQL 存储过程的接口。JDBC API 提供了一个存储过程 SQL 转义语法,该语法允许对所有 RDBMS 使用标准方式调用存储过程。此转义语法有一个包含结果参数的形式和一个不包含结果参数的形式。如果使用结果参数,则必须将其注册为 OUT 型参数。其他参数可用于输入、输出或同时用于二者。参数是根据编号按顺序引用的,第一个参数的编号是 1。 {?= call [,, ...]} {call [,, ...]} IN 参数值是使用从 PreparedStatement 中继承的 set 方法设置的。在执行存储过程之前,必须注册所有 OUT 参数的类型;它们的值是在执行后通过此类提供的 get 方法检索的。 4.需要注意存储过程调用的方法。 5.registerOutParameter 的使用方法。 void registerOutParameter(int parameterIndex, int sqlType) throws SQLException 按顺序位置 parameterIndex 将 OUT 参数注册为 JDBC 类型 sqlType。所有 OUT 参数都必须在执行存储过程前注册。由 sqlType 指定的 OUT 参数的JDBC 类型确定必须用于 get 方法来读取该参数值的 Java 类型。如果预期返回给此输出参数的 JDBC 类型是取决于此特定数据库的,则 sqlType 应该是java.sql.Types.OTHER。 方法 getObject(int) 检索该值。 参数: parameterIndex - 第一个参数是 1,第二个参数是 2,依此类推。 sqlType - java.sql.Types 定义的 JDBC 类型代码。如果参数是 JDBC 类型NUMERIC 或 DECIMAL,则应使用接受标度值的那种。 下面是一个具体的程序实例: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package gui.database;

mysql分享(1)-sql语句执行的11个步骤

IREDPURE mysql执行查询语句的11个步骤(分享1) ZERO 2016/02/19

每个人都会犯错误,有的人把犯过的错误记录下来,进一步总结,形成了自己的一套理论;有的人,则在同一个错误上一错再错,不停的抱怨,然后 再犯错,然后再抱怨,产生了一个死循环…… 1、项目结束后的思考 每个项目的结束,每个人都会有自己的收获,不同水平的人总结出来的东西可能不一样!但是对自己而言,都是进步,都是让自己在原有的基础上强大 了一点点。我们在每个项目结束后,都应该对自己做一个总结,这是我们强大的来源,日记月累,必定是一笔不小的财富! 2、mysql查询语句执行的11个步骤 (8) select (9) distinct (1) from (1) (3) join (1) (2) on (4) where (5) group by (6) with {cube | rollup} (7) having (10) order by (11) limit 以上是这个11个步骤,这是《mysql技术内幕之sql编程》这本书上面得出的结论,有兴趣的同学也可以去看下,很不错的一本书! ps: Paul DuBois( 杜波依斯) Sun 公司MySQL文档团队的技术作者、开源社区和MySQL社区活跃的技术专家,同时也是一名数据库管理员。他曾参 与过MySQL在线文档的编写工作 接下来我们举一个例子,分别解释sql语句的执行流程! 3、举例说明sql语句的执行流程 【1】进行准备工作 CREATE TABLE `Customer` ( `CustomerID` varchar(10) NOT NULL, `CityName` varchar(10) NOT NULL, PRIMARY KEY (`CustomerID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; LOCK TABLES `Customer` WRITE; INSERT INTO `Customer` VALUES ('163','hangzhou'),('9you','shanghai'),('tx','hangzhou'), ('baidu','hangzhou'); UNLOCK TABLES; ================================================================================================================= CREATE TABLE `Orders` ( `OrdersID` int(11) NOT NULL AUTO_INCREMENT, `CustomerID` varchar(10) DEFAULT NULL, PRIMARY KEY (`OrdersID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; LOCK TABLES `Orders` WRITE; INSERT INTO `Orders` VALUES (1,'163'),(2,'163'),(3,'9you'),(4,'9you'),(5,'9you'),(6,'tx'),(7,null); UNLOCK TABLES; =====================================================================================================最终结果如下: 通过如下语句查询来杭州,且订单小于2的用户,并且查询出来他们的订单数量,查询的结果按照订单数从大到小排列: select Customer.CustomerID, Customer.CityName, count(Orders.CustomerID) as OrdersNumber from Customer left join Orders on Customer.CustomerID = Orders.CustomerID where Customer.CityName='HangZhou' group by Customer.CustomerID having count(Orders.CustomerID) < 2 order by OrdersNumber desc; ps:在得出正确的语句之前,我写了两次错误的sql,个人认为还是很有借鉴意义的:

JAVA通过MyBatis调用MySql存储过程和函数

JAV A通过MyBatis调用MySql存储过程和函数 1.引言 无论是采用SPRING MVC框架开发WEB画面,还是开发需按一定时间间隔执行的批处理,都可能要调用数据库的存储过程或函数。其间调用参数设置不正会浪费大量调试时间初学者甚至放弃使用存储过程。本文记录了通过MyBatis调用MySql存储过程和函数的具体参数设置内容,供参考。 2.MySql存储过程例 /*全公司员工下一年度带薪休假一发赋予处理*/ CREATE DEFINER=`DBuser`@`%` PROCEDURE `paid_vacation_compute `( OUT p_返回值 INT(11) , INOUT p_员工号 CHAR(3) , p_操作者ID VARCHAR(3)) PROC_START: BEGIN /* 变量声明 */ DECLARE done INT; #异常退出控制变量 DECLARE empNo CHAR(3); #员工号 DECLARE dateHire date; #分公司就职日 DECLARE workYears INT; #集团内工作年数 DECLARE lastYearRemainDays FLOAT; #昨年残日数(允许以小时为单位休假) DECLARE nowYearleaveDays FLOAT; #今年休暇日数(允许以小时为单位休假) DECLARE elapseYear INT; #入集团经过年度数 /* 游标声明 */ #上年带薪休假数据 DECLARE staffPaidVacationDaysCur CURSOR FOR SELECT a.EMP_NO, #员工号 a.DATE_HIRE, #入职日期 a.WORK_YEARS, #工作年限 b.REMAIN_DAYS # 上年带薪休假应休但未休残日数 FROM T_EMPLOYEE AS a, T_PAID_VACATION AS b WHERE a. EMP_NO = b. EMP_NO /* 程序退出规定声明 */ DECLARE CONTINUE HANDLER FOR NOT FOUND SET SET done = 1;

SQL语句执行效率及分析

SQL语句执行效率及分析 2. SQL提高查询效率 2008-05-12 21:20 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如: select id from t where num is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。 4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用 索引而进行全表扫描,如: select id from t where num=10 or num=20 可以这样查询: select id from t where num=10 union all select id from t where num=20 5.in 和 not in 也要慎用,否则会导致全表扫描,如: select id from t where num in(1,2,3) 对于连续的数值,能用 between 就不要用 in 了: select id from t where num between 1 and 3 6.下面的查询也将导致全表扫描: select id from t where name like '%abc%' 若要提高效率,可以考虑全文检索。 7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因 而无法作为索引选择的输入项。如下面语句将进行全表扫描: select id from t where num=@num 可以改为强制查询使用索引: select id from t with(index(索引名)) where num=@num 8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用 索引而进行全表扫描。如:

使用JAVA存储过程导入EXCEL文件操作指南

利用JAV A存储过程进行EXCEL导入 导入思路 顾问提供的PO导入FORM已经给了我们一个导入数据到系统的一个模板,基本能够满足我们的要求,该FORM主要完成以下动作: 1.显示文件上传页面给用户选择文件 2.将文本文件以字符流的形式存入到fnd_lobs表的BLOB字段 3.从BLOB字段读取数据,通过逗号分割(,)的方式从BLOB字段获取每个字段的值 4.存入系统临时表进行后续的导入处理 该方法的主要缺点在于需要用户手工将EXCEL文件存为.csv文件(即普通.txt文件),以及通过逗号分割进行解析字符流的方式进行文本文件的处理,如果用户提供的EXCEL单元格的数据中有逗号(,),则解析会出错。 该方法可以利用JAV A存储过程进行改进为: 1.在上传页面用户直接上传EXCEL文件 2.将文本文件以字符流的形式存入到fnd_lobs表的BLOB字段 3.以BLOB字段作为文件输入流,调用JAV A存储过程获取EXCEL文件内容 4.存入系统临时表进行后续的导入处理 在新方法的第3步中,调用JAV A类型的存储过程,引用处理EXCEL的JAV A API进行文件内容的读取。由于是直接解析EXCEL文件,可以减少出错的概率,另外也可以通过对API 进行替换的方式来处理其他类型的文件,如WORD或XML文件等。 导入实现 具体细节部分请参照附件的XXEXCELIMPORT.fmb文件,以下部分只说明主要步骤。 创建FORM 1.创建临时表块以及上传功能按钮 2.添加上传文件功能, 以上FORM部分具体参照顾问提供的PO导入FORM以及其中的文件上传程序段UPLOAD_FILE

SQL语句执行顺序

一、sql语句的执行步骤: 1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。 2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。 3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。 4)表达式转换,将复杂的 SQL 表达式转换为较简单的等效连接表达式。 5)选择优化器,不同的优化器一般产生不同的“执行计划” 6)选择连接方式,ORACLE有三种连接方式,对多表连接 ORACLE 可选择适当的连接方式。7)选择连接顺序,对多表连接 ORACLE 选择哪一对表先连接,选择这两表中哪个表做为源数据表。 8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。 9)运行“执行计划” 二、oracle 共享原理: ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用 三、oracle 语句提高查询效率的方法:1: where column in(select * from ... where ...); 2:... where exists (select 'X' from ...where ...); 第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间 Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中避免使用having字句避免使用HAVING子句, HAVING 只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作. 如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销 SQL Select语句完整的执行顺序: 1、from子句组装来自不同数据源的数据; 2、where子句基于指定的条件对记录行进行筛选; 3、group by子句将数据划分为多个分组; 4、使用聚集函数进行计算; 5、使用having子句筛选分组; 6、计算所有的表达式; 7、使用order by对结果集进行排序。

使用Java语言开发存储过程

Oracle8i中使用Java语言来开发存储过程 本篇文章来源与时代朝阳数据库(原晓通数据库)培训部Oracle 资料库。 在Oracle8i之前,开发人员只能使用PL/SQL来开发存储过程。而在Oracle8i 之中,不仅可以使用原有的PL/SQL开发存储过程,而且也可以使用Java语言来开发存储过程。本篇文章将简单介绍关于这方面的知识,包括以下内容: ●存储过程简介; ●Java存储过程 ●Java存储过程的开发步骤 ●使用Java开发过程; ●使用Java开发函数; ●使用Java开发包; ●使用Java开发触发器; ●使用Java开发对象方法; ●使用JDeveloper开发JSP。 存储过程简介 存储过程是存储在数据库中的一段存储程序。当创建存储过程时,系统会对其进行编译,并将执行代码存储到数据库中。 1.设计存储过程的方针 ●在定义存储过程时,要使用其完成单一、相对集中的任务。

●在定义存储过程时,不要定义已经由其它特征所提供功能的过程。例如, 不要定义强制数据完整性的过程(使用完整性约束)。 2.存储过程的优点 1)安全性 当创建了存储过程之后,可以将执行该过程的权限授予其它用户,从而使得他可以执行特定的数据库操作,而不能访问其它模式对象(例如表)。例如,你可以将执行过程(更新表)的权限授予其它用户,但不授予它们直接访问该表的权限。 2)性能 ●存储过程只被发送到数据库一次,相对于SQL语句或PL/SQL块而言, 其网络通信量更小。 ●当调用存储过程时,数据库会直接运行该存储过程,无需进行编译。相 对于SQL语句或PL/SQL块而言,其执行速度更快。 3)内存分配 存储过程充分利用了Oracle共享内存的能力。在将存储过程装载到内存中后,多个用户可以同时调用该存储过程,从而降低了应用对Oracle的实际内存需求。 4)生产力 存储过程提高了开发生产力。通过将公共集合编写为存储过程,避免了冗余代码,从而提高了开发生产力。例如,我们可以编写用于插入、更新、删除AUTHS

mysql存储过程.详细说明,java代码调用过程

Mysql存储过程调用 说明: 由括号包围的参数列必须总是存在。如果没有参数,也该使用一个空参数列()。每个参数默认都是一个IN参数。要指定为其它参数,可在参数名之前使用关键词OUT或INOUT 在mysql客户端定义存储过程的时候使用delimiter命令来把语句定界符从;变为//。 当使用delimiter命令时,你应该避免使用反斜杠(‘"’)字符,因为那是MySQL的转义字符。 1、创建过程格式: Mysql> drop procedure if exists user_findById; Mysql> delimiter // Create procedure user_findById(in n int) Begin Select * from user where id= n; End // 调用过程: Mysql> set @n=1; --定义变量 Call user_findById(@n);--调用过程 // --显示结果 ======================================================

例2: Mysql> drop procedure if exists user_count; Mysql> delimiter // Create procedure user_count(out count int) Begin Select count(*) into count from user; End // --结束 注意: MySQL存储过程 “in”参数: 跟 C语言的函数参数的值传递类似, MySQL存储过程内部可能会修改此,参数,但对 in类型参数的修改,对调用者(caller)来说是不可见的(not visible)。 “out”参数: 从存储过程内部传值给调用者。在存储过程内部,该参数初始值为 null,无论调用者是否给存储过程参数设置值inout参数跟 out类似,都可以从存储过程内部传值给调用者。不同的是:调用者还可以通过 inout参数传递值给存储过程。 总结:如果仅仅想把数据传给MySQL存储过程,那就使用“in”类型 参数;如果仅仅从MySQL存储过程返回值,那就使用“out”类型参数;如果需要把数据传给MySQL存储过程,还要经过一些计算后再传回给我们,

执行一条sql语句update多条记录实现思路

执行一条sql语句update多条记录实现思路 如果你想更新多行数据,并且每行记录的各字段值都是各不一样,怎么办? 通常情况下,我们会使用以下SQL语句来更新字段值: UPDATE mytable SET myfield='value' WHERE other_field='other_value'; 但是,如果你想更新多行数据,并且每行记录的各字段值都是各不一样,你会怎么办呢?举个例子,我的博客有三个分类目录(免费资源、教程指南、橱窗展示),这些分类目录的信息存储在数据库表categories中,并且设置了显示顺序字段 display_order,每个分类占一行记录。如果我想重新编排这些分类目录的顺序,例如改成(教程指南、橱窗展示、免费资源),这时就需要更新categories表相应行的display_order字段,这就涉及到更新多行记录的问题了,刚开始你可能会想到使用循环执行多条UPDATE语句的方式,就像以下的php 程序示例: ? 1 2 3 4 5 foreach ($display_order as $id => $ordinal) { $sql="UPDATE categories SET display_order = $ordinal WHERE id = $id"; mysql_query($sql); } 这种方法并没有什么任何错误,并且代码简单易懂,但是在循环语句中执行了不止一次SQL 查询,在做系统优化的时候,我们总是想尽可能的减少数据库查询的次数,以减少资源占用,同时可以提高系统速度。 幸运的是,还有更好的解决方案,下面列举两种常用的方案只不过SQL语句稍微复杂点,但是只需执行一次查询即可,语法如下: ? 1 2 3 4 5 6 7 8 ?第一种:IF--THEN语句结合UPDATE mytable SET myfield = CASE other_field WHEN 1 THEN 'value' WHEN 2 THEN 'value' WHEN 3 THEN 'value' END

用JDBC操作Oracle的存储过程返回值.

用JDBC操作Oracle的存储过程返回值 Oracle的存储过程可以返回任何类型,包括一个ResultSet,JDBC自带的CallableStatement可以提供操作这些返回值得借口,其中我们可以通过registerOutParameter来注册需要返回的类型。CallableStatement是PrepareStatement的一个子类,但提供了返回和注册Out类型参数的功能。我们看一下例子,在Oracle里面我们定义了一个包如下: create or replace package GP_TESTP is type my_dCursor is ref cursor; procedure GP_Test(m_cursor2 OUT my_dCursor; end GP_TESTP; create or replace package body GP_TESTP is procedure GP_Test(m_cursor2 OUT my_dCursor is begin open m_cursor2 for select bom.material_no,bom.product_no from gp2_bom bom where bom.year=2006 ; end GP_Test; end GP_TESTP; 在JDBC里面我们可以通过如下的接口来得到返回的动态游标的内容 Global.start(; //初始化连接池 ConnectionWrapper wrapper=ConnectionPoolFactory.getPoolInstance(.borrowConnection(;//从连接池里面返回连接 Connection conn=wrapper.getConnection(; try { String callSql="{call GP_TESTP.GP_Test(?}"; CallableStatement cs = null; ResultSet rs=null; cs = conn.prepareCall(callSql; cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR; cs.execute(; rs = (ResultSetcs.getObject(2; while(rs.next({ //String s=rs.get(""; String component=rs.getString(2; String productNo=rs.getString(4; System.out.println("component="+component+"-------productNo="+productNo; } } catch (SQLException e { // TODO Auto-generated catch block e.printStackTrace(; } 注意兰颜色的代码是注册动态游标和返回结果集的关键代码。 ======================================= 2008年07月06日星期日 07:41 P.M.一:无返回值的存储过程存储过程为: 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;

oracle sql语句执行顺序

要知道SQL语句,我想我们有必要知道SQL Server查询分析器怎么执行我们的SQL语句的,我们很多人会看执行计划,或者用Profiler来监视和调优查询语句或者存储过程慢的原因,但是如果我们知道查询分析器的执行逻辑顺序,下手的时候就胸有成竹,那么下手是不是有把握点呢? 一、查询的逻辑执行顺序 (1) FROM left_table (3) join_type JOIN right_table (2) ON join_condition (4) WHERE where_condition (5) GROUP BY group_by_list (6) WITH {cube | rollup} (7) HAVING having_condition (8) SELECT (9) DISTINCT (11) top_specification select_list (9) ORDER BY order_by_list 标准的SQL 的解析顺序为: (1) FROM 子句组装来自不同数据源的数据 (2) WHERE 子句基于指定的条件对记录进行筛选 (3) GROUP BY 子句将数据划分为多个分组 (4) 使用聚合函数(avg)进行计算 (5) 使用HAVING子句筛选分组 (6) 计算所有的表达式 (7) 使用ORDER BY对结果集进行排序 二、执行顺序 1. FROM:对FROM子句中前两个表执行笛卡尔积生成虚拟表vt1 2. ON: 对vt1表应用ON筛选器只有满足join_condition 为真的行才被插入vt2 3. OUTER(join):如果指定了OUTER JOIN保留表(preserved table)中未找到的行将行作为外部行添加到vt2,生成t3,如果from包含两个以上表,则对上一个联结生成的结果表和下一个表重复执行步骤和步骤直接结束。 4. WHERE:对vt3应用WHERE 筛选器只有使where_condition 为true的行才被插入vt4 5. GROUP BY:按GROUP BY子句中的列列表对vt4中的行分组生成vt5 6. CUBE|ROLLUP:把超组(supergroups)插入vt6,生成vt6 7. HAVING:对vt6应用HAVING筛选器只有使having_condition 为true的组才插入vt7 8. SELECT:处理select列表产生vt8 9. DISTINCT:将重复的行从vt8中去除产生vt9 10. ORDER BY:将vt9的行按order by子句中的列列表排序生成一个游标vc10 11. TOP:从vc10的开始处选择指定数量或比例的行生成vt11 并返回调用者 看到这里,那么用过Linq to SQL的语法有点相似啊?如果我们我们了解了SQL Server 执行顺序,那么我们就接下来进一步养成日常SQL的好习惯,也就是在实现功能的同时有考虑性能的思想,数据库是能进行集合运算的工具,我们应该尽量的利用这个工具,所谓集合运算实际就是批量运算,就是尽量减少在客户端进行大数据量的循环操作,而用SQL语句或者存储过程代替。 三、只返回需要的数据 返回数据到客户端至少需要数据库提取数据、网络传输数据、客户端接收数据以及客户

java调用存储过程返回结果集,返回字符串

package com.utour.util; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array; /** * java调用存储过程 * * @author Administrator * */ public class JavaCallPro { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub String s = testOutParams(); System.out.println(s); // // List list = test(); // // for(int i=0;i

SQL语句执行效率及分析(note)

SQL语句执行效率及分析(note) 1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2000 目的: 查询性能测试,比较两种查询的性能 SQL查询效率step by step -- setp 1. -- 建表 create table t_userinfo ( userid int identity(1,1) primary key nonclustered, nick varchar(50) not null default '', classid int not null default 0, writetime datetime not null default getdate() ) go -- 建索引 create clustered index ix_userinfo_classid on t_userinfo(classid) go -- step 2. declare @i int declare @k int declare @nick varchar(10) set @i = 1 while @i<1000000 begin set @k = @i % 10 set @nick = convert(varchar,@i) insert into t_userinfo(nick,classid,writetime) values(@nick,@k,getdate()) set @i = @i + 1

end -- 耗时08:27 ,需要耐心等待 -- step 3. select top 20 userid,nick,classid,writetime from t_userinfo where userid not in ( select top 900000 userid from t_userinfo order by userid asc ) -- 耗时8 秒,够长的 -- step 4. select https://www.360docs.net/doc/7734889.html,erid,b.nick,b.classid,b.writetime from ( select top 20 https://www.360docs.net/doc/7734889.html,erid from ( select top 900020 userid from t_userinfo order by userid asc ) a order by https://www.360docs.net/doc/7734889.html,erid desc ) a inner join t_userinfo b on https://www.360docs.net/doc/7734889.html,erid = https://www.360docs.net/doc/7734889.html,erid order by https://www.360docs.net/doc/7734889.html,erid asc -- 耗时1 秒,太快了吧,不可以思议 -- step 5 where 查询 select top 20 userid,nick,classid,writetime from t_userinfo where classid = 1 and userid not in ( select top 90000 userid from t_userinfo where classid = 1 order by userid asc ) -- 耗时2 秒 -- step 6 where 查询 select https://www.360docs.net/doc/7734889.html,erid,b.nick,b.classid,b.writetime from ( select top 20 https://www.360docs.net/doc/7734889.html,erid from ( select top 90000 userid from t_userinfo

Java调用SQL Server存储过程

Java调用SQL Server存储过程 Java调用SQL Server的存储过程详解,主要内容: ●使用不带参数的存储过程 ●使用带有输入参数的存储过程 ●使用带有输出参数的存储过程 ●使用带有返回状态的存储过程 ●使用带有更新计数的存储过程 1.使用不带参数的存储过程 使用JDBC 驱动程序调用不带参数的存储过程时,必须使用call SQL 转义序列。不带参数的call 转义序列的语法如下所示: 实例:在SQL Server 2005 AdventureWorks示例数据库中创建以下存储过程: 此存储过程返回单个结果集,其中包含一列数据(由Person.Contact 表中前十个联系人的称呼、名称和姓氏组成)。 在下面的实例中,将向函数传递AdventureWorks示例数据库的打开连接,然后使用executeQuery方法调用GetContactFormalNames存储过程。

2.使用带有输入参数的存储过程 使用JDBC 驱动程序调用带参数的存储过程时,必须结合SQLServerConnection 类的prepareCall方法使用call SQL转义序列。带有IN参数的call转义序列的语法如下所示: 构造call转义序列时,请使用?(问号)字符来指定IN参数。此字符充当要传递给该存储过程的参数值的占位符。可以使用SQLServerPreparedStatement类的setter方法之一为参数指定值。可使用的setter方法由IN参数的数据类型决定。 向setter方法传递值时,不仅需要指定要在参数中使用的实际值,还必须指定参数在存储过程中的序数位置。例如,如果存储过程包含单个IN参数,则其序数值为1。如果存储过程包含两个参数,则第一个序数值为1,第二个序数值为2。 作为调用包含IN参数的存储过程的实例,使用SQL Server 2005 AdventureWorks示例数据库中的uspGetEmployeeManagers存储过程。此存储过程接受名为EmployeeID的单个输入参数(它是一个整数值),然后基于指定的EmployeeID返回雇员及其经理的递归列表。下面是调用此存储过程的Java代码:

解析SQL执行过程

为了将用户写的SQL文本转化为Oracle认识的且可执行的语句,这个过程就叫做解析过程。解析分为硬解析和软解析。一条SQL语句在第一次被执行时必须进行硬解析。 当客户端发出一条SQL语句(也可以是一个存储过程或者一个匿名PL/SQL块)进入shared pool时(注意,我们从前面已经知道,Oracle对这些SQL不叫做SQL语句,而是称为游标。因为Oracle在处理SQL时,需要很多相关的辅助信息,这些辅助信息与SQL语句一起组成了游标),Oracle首先将SQL文本转化为ASCII值,然后根据hash函数计算其对应的hash值(hash_value)。根据计算出的hash值到library cache中找到对应的bucket,然后比较bucket里是否存在该SQL语句。 如果不存在,则需要按照我们前面所描述的,获得shared pool latch,然后在shared pool 中的可用chunk链表(也就是bucket)上找到一个可用的chunk,之后释放shared pool latch。在获得了chunk以后,这块chunk就可以认为是进入了library cache。接下来,进行硬解析过程。硬解析包括以下几个步骤。 对SQL语句进行文法检查,看是否有文法错误。比如没有写from、select拼写错误等。如果存在文法错误,则退出解析过程。 到数据字典里校验SQL语句涉及的对象和列是否都存在。如果不存在,则退出解析过程。这个过程会加载dictionary cache。 将对象进行名称转换。比如将同名词翻译成实际的对象等。比如select * from t中,t是一个同名词,指向hr.t1,于是Oracle将t转换为hr.t1。如果转换失败,则退出解析过程。 检查发出SQL语句的用户是否具有访问SQL语句里所引用的对象的权限。如果没有权限,则退出解析过程。 通过优化器创建一个最优的执行计划。这个过程会根据数据字典里记录的对象的统计信息,来计算最优的执行计划。这一步牵涉大量数学运算,是最消耗CPU资源的。 将该游标所产生的执行计划、SQL文本等装载进library cache的heap中。 在硬解析的过程中,进程会一直持有library cache latch,直到硬解析结束为止。硬解析结束以后,会为SQL语句产生两个游标,一个是父游标,另一个是子游标。父游标里主要包含两种信息:SQL文本以及优化目标(optimizer goal)。父游标在第一次打开时被锁定,直到其他所有的session都关闭该游标后才被解锁。当父游标被锁定的时候是不能被交换出library cache的,只有在解锁以后才能被交换出library cache。父游标被交换出内存时,父游标对应的所有子游标也被交换出library cache。子游标包括游标所有的信息,比如具体的执行计划、绑定变量等。子游标随时可以被交换出library cache,当子游标被交换出library cache

PLSQL怎么执行SQL语句

通过f5查看到的执行计划,其实是pl/sql developer工具内部执行查询 plan_table表然后格式化的结果。 select * from plan_table where statement_id=...。其中 description列描述当前的数据库操作, object owner列表示对象所属用户, object name表示操作的对象, cost列表示当前操作的代价(消耗),这个列基本上就是评价sql语句的优劣,cardinality列表示操作影响的行数, bytes列表示字节数篇二:plsqldeveloper工具使用教程 plsql入门 pl/sql的概述 pl/sql的优势 pl/sql是一种块结构的语言,允许你将业务逻辑封装在一起,这是到目前为止使用pl/sql的最大优势 pl/sql是在服务器上运行,可以与数据库和sql引擎直接进行交互, pl/sql是什么? (procedural language/sql) 是oracle在标准的sql语言上的扩展,pl/sql不仅允许嵌入sql语言,还可以定义变量和常量,允许使用条件语句和循环语句,允许使用列外处理各种错误,这样使得它的功能变得更加强大。 特性: 减少java程序的复杂性 一.过程,函数,触发器是pl/sql编写的 二.过程、函数、触发器是在oracle中 三. pl/sql是非常强大的数据库过程语言 四.过程,函数可以再java程序中调用 为什么学? a) 提高应用程序的运行性能 b) 模块化的设计思想[分页的过程,订单的过程,转账的过程] c) 减少网络传输量(传统的方法,用sql语句传输!现在就只需要调用存储过程) d) 提高安全性(传统sql 可以看到表名字段等…) 不好: 移植性不好,(你写好的存储过程,函数等当我们要换数据库时,这些东西就没用了)开发工具: 1. sqlplus 开发工具 是oracle公司提供的一个工具,这个因为我们在以前介绍过: 2. pl/sql developer开发工具 pl/sql developer是用于开发pl/sql块的集成开发环境(ide) 它是一个独立的产品,而不是oracle的一个附带品, createprocedure sp_pro1//存储过程名字 is begin ---执行部分 insert into mytest values(‘’,’’); end; / 查看错误信息

相关文档
最新文档