什么是存储过程有什么优点

什么是存储过程有什么优点,第1张

存储过程是事先经过编译并存储在数据库中的一段SQL语句的集合,调用存储过程可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是有好处的。

优点:

1、重复使用:存储过程可以重复使用,从而可以减少数据库开发人员的工作量。

2、减少网络流量:存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。

3、安全性:参数化的存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。

扩展资料

存储过程的缺点:

1、更改比较繁琐:如果更改范围大到需要对输入存储过程的参数进行更改,或者要更改由其返回的数据,则仍需要更新程序集中的代码以添加参数、更新 GetValue() 调用,等等,这时候估计比较繁琐。

2、可移植性差:由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。如果应用程序的可移植性在您的环境中非常重要,则需要将业务逻辑封装在不特定于 RDBMS 的中间层中。

参考资料来源:百度百科-存储过程

本文阐述了怎么使用DBMS存储过程 阐述了使用存储过程的基本的和高级特性 比如返回ResultSet 本文假设你对DBMS和JDBC已经非常熟悉 也假设你能够毫无障碍地阅读其它语言写成的代码(即不是Java的语言) 但是 并不要求你有任何存储过程的编程经历

存储过程是指保存在数据库并在数据库端执行的程序 你可以使用特殊的语法在Java类中调用存储过程 在调用时 存储过程的名称及指定的参数通过JDBC连接发送给DBMS 执行存储过程并通过连接(如果有)返回结果

使用存储过程拥有和使用基于EJB或CORBA这样的应用服务器一样的好处 区别是存储过程可以从很多流行的DBMS中免费使用 而应用服务器大都非常昂贵 这并不只是许可证费用的问题 使用应用服务器所需要花费的管理 编写代码的费用 以及客户程序所增加的复杂性 都可以通过DBMS中的存储过程所整个地替代

你可以使用Java Python Perl或C编写存储过程 但是通常使用你的DBMS所指定的特定语言 Oracle使用PL/SQL PostgreSQL使用pl/pgsql DB 使用Procedural SQL 这些语言都非常相似 在它们之间移植存储过程并不比在Sun的EJB规范不同实现版本之间移植Session Bean困难 并且 存储过程是为嵌入SQL所设计 这使得它们比Java或C等语言更加友好地方式表达数据库的机制

因为存储过程运行在DBMS自身 这可以帮助减少应用程序中的等待时间 不是在Java代码中执行 个或 个SQL语句 而只需要在服务器端执行 个存储过程 网络上的数据往返次数的减少可以戏剧性地优化性能

使用存储过程

简单的老的JDBC通过CallableStatement类支持存储过程的调用 该类实际上是PreparedStatement的一个子类 假设我们有一个poets数据库 数据库中有一个设置诗人逝世年龄的存储过程 下面是对老酒鬼Dylan Thomas(old soak Dylan Thomas 不指定是否有关典故 文化 请批评指正 译注)进行调用的详细代码

try{ int age = ; String poetName = dylan thomas ; CallableStatement proc = connection prepareCall( { call set_death_age( ) } ); proc setString( poetName); proc setInt( age); cs execute();}catch (SQLException e){ // }

传给prepareCall方法的字串是存储过程调用的书写规范 它指定了存储过程的名称 ?代表了你需要指定的参数

和JDBC集成是存储过程的一个很大的便利 为了从应用中调用存储过程 不需要存根(stub)类或者配置文件 除了你的DBMS的JDBC驱动程序外什么也不需要

当这段代码执行时 数据库的存储过程就被调用 我们没有去获取结果 因为该存储过程并不返回结果 执行成功或失败将通过例外得知 失败可能意味着调用存储过程时的失败(比如提供的一个参数的类型不正确) 或者一个应用程序的失败(比如抛出一个例外指示在poets数据库中并不存在 Dylan Thomas )

结合SQL *** 作与存储过程

映射Java对象到SQL表中的行相当简单 但是通常需要执行几个SQL语句 可能是一个SELECT查找ID 然后一个INSERT插入指定ID的数据 在高度规格化(符合更高的范式 译注)的数据库模式中 可能需要多个表的更新 因此需要更多的语句 Java代码会很快地膨胀 每一个语句的网络开销也迅速增加

将这些SQL语句转移到一个存储过程中将大大简化代码 仅涉及一次网络调用 所有关联的SQL *** 作都可以在数据库内部发生 并且 存储过程语言 例如PL/SQL 允许使用SQL语法 这比Java代码更加自然 下面是我们早期的存储过程 使用Oracle的PL/SQL语言编写

create procedure set_death_age(poet VARCHAR poet_age NUMBER)poet_id NUMBER;beginSELECT id INTO poet_id FROM poets WHERE name = poet;INSERT INTO deaths (mort_id age) VALUES (poet_id poet_age);end set_death_age;

很独特?不 我打赌你一定期待看到一个poets表上的UPDATE 这也暗示了使用存储过程实现是多么容易的一件事情 set_death_age几乎可以肯定是一个很烂的实现 我们应该在poets表中添加一列来存储逝世年龄 Java代码中并不关心数据库模式是怎么实现的 因为它仅调用存储过程 我们以后可以改变数据库模式以提高性能 但是我们不必修改我们代码

下面是调用上面存储过程的Java代码

public static void setDeathAge(Poet dyingBard int age)throws SQLException{ Connection con = null; CallableStatement proc = null;

try {con = connectionPool getConnection();proc = con prepareCall( { call set_death_age( ) } );proc setString( dyingBard getName());proc setInt( age);proc execute(); } finally {try{ proc close();}catch (SQLException e) {}con close(); }}

为了确保可维护性 建议使用像这儿这样的static方法 这也使得调用存储过程的代码集中在一个简单的模版代码中 如果你用到许多存储过程 就会发现仅需要拷贝 粘贴就可以创建新的方法 因为代码的模版化 甚至也可以通过脚本自动生产调用存储过程的代码

Functions

存储过程可以有返回值 所以CallableStatement类有类似getResultSet这样的方法来获取返回值 当存储过程返回一个值时 你必须使用registerOutParameter方法告诉JDBC驱动器该值的SQL类型是什么 你也必须调整存储过程调用来指示该过程返回一个值

下面接着上面的例子 这次我们查询Dylan Thomas逝世时的年龄 这次的存储过程使用PostgreSQL的pl/pgsql

create function snuffed_it_when (VARCHAR) returns integer declarepoet_id NUMBER;poet_age NUMBER;begin first get the id associated with the poet SELECT id INTO poet_id FROM poets WHERE name = $ ; get and return the age SELECT age INTO poet_age FROM deaths WHERE mort_id = poet_id;return age;end; language pl/pgsql ;

另外 注意pl/pgsql参数名通过Unix和DOS脚本的$n语法引用 同时 也注意嵌入的注释 这是和Java代码相比的另一个优越性 在Java中写这样的注释当然是可以的 但是看起来很凌乱 并且和SQL语句脱节 必须嵌入到Java String中

下面是调用这个存储过程的Java代码

connection setAutoCommit(false);CallableStatement proc =connection prepareCall( { = call snuffed_it_when() } );proc registerOutParameter( Types INTEGER);proc setString( poetName);cs execute();int age = proc getInt( );

如果指定了错误的返回值类型会怎样?那么 当调用存储过程时将抛出一个RuntimeException 正如你在ResultSet *** 作中使用了一个错误的类型所碰到的一样

复杂的返回值

关于存储过程的知识 很多人好像就熟悉我们所讨论的这些 如果这是存储过程的全部功能 那么存储过程就不是其它远程执行机制的替换方案了 存储过程的功能比这强大得多

当你执行一个SQL查询时 DBMS创建一个叫做cursor(游标)的数据库对象 用于在返回结果中迭代每一行 ResultSet是当前时间点的游标的一个表示 这就是为什么没有缓存或者特定数据库的支持 你只能在ResultSet中向前移动

某些DBMS允许从存储过程中返回游标的一个引用 JDBC并不支持这个功能 但是Oracle PostgreSQL和DB 的JDBC驱动器都支持在ResultSet上打开到游标的指针(pointer)

设想列出所有没有活到退休年龄的诗人 下面是完成这个功能的存储过程 返回一个打开的游标 同样也使用PostgreSQL的pl/pgsql语言

create procedure list_early_deaths () return refcursor as declaretoesup refcursor;beginopen toesup forSELECT poets name deaths ageFROM poets deaths all entries in deaths are for poets but the table might bee generic WHERE poets id = deaths mort_idAND deaths age < ;return toesup;end; language plpgsql ;

下面是调用该存储过程的Java方法 将结果输出到PrintWriter

PrintWriter:

static void sendEarlyDeaths(PrintWriter out){ Connection con = null; CallableStatement toesUp = null; try {con = ConnectionPool getConnection();

// PostgreSQL needs a transaction to do this con setAutoCommit(false);

// Setup the call CallableStatement toesUp= connection prepareCall( { = call list_early_deaths () } );toesUp registerOutParameter( Types OTHER);getResults execute();

ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); out println(name + was + age + years old );}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}

因为JDBC并不直接支持从存储过程中返回游标 我们使用Types OTHER来指示存储过程的返回类型 然后调用getObject()方法并对返回值进行强制类型转换

这个调用存储过程的Java方法是mapping的一个好例子 Mapping是对一个集上的 *** 作进行抽象的方法 不是在这个过程上返回一个集 我们可以把 *** 作传送进去执行 本例中 *** 作就是把ResultSet打印到一个输出流 这是一个值得举例的很常用的例子 下面是调用同一个存储过程的另外一个方法实现

public class ProcessPoetDeaths{ public abstract void sendDeath(String name int age);}

static void mapEarlyDeaths(ProcessPoetDeaths mapper){ Connection con = null; CallableStatement toesUp = null; try {con = ConnectionPool getConnection();con setAutoCommit(false);

CallableStatement toesUp= connection prepareCall( { = call list_early_deaths () } );toesUp registerOutParameter( Types OTHER);getResults execute();

ResultSet rs = (ResultSet) getResults getObject( );while (rs next()){ String name = rs getString( ); int age = rs getInt( ); mapper sendDeath(name age);}rs close(); } catch (SQLException e) {// We should protect these calls toesUp close();con close(); }}

这允许在ResultSet数据上执行任意的处理 而不需要改变或者复制获取ResultSet的方法

static void sendEarlyDeaths(final PrintWriter out){ ProcessPoetDeaths myMapper = new ProcessPoetDeaths() {public void sendDeath(String name int age){ out println(name + was + age + years old );} }; mapEarlyDeaths(myMapper);}

这个方法使用ProcessPoetDeaths的一个匿名实例调用mapEarlyDeaths 该实例拥有sendDeath方法的一个实现 和我们上面的例子一样的方式把结果写入到输出流 当然 这个技巧并不是存储过程特有的 但是和存储过程中返回的ResultSet结合使用 是一个非常强大的工具

结论

存储过程可以帮助你在代码中分离逻辑 这基本上总是有益的 这个分离的好处有

快速创建应用 使用和应用一起改变和改善的数据库模式

数据库模式可以在以后改变而不影响Java对象 当我们完成应用后 可以重新设计更好的模式

存储过程通过更好的SQL嵌入使得复杂的SQL更容易理解

编写存储过程比在Java中编写嵌入的SQL拥有更好的工具——大部分编辑器都提供语法高亮!

存储过程可以在任何SQL命令行中测试 这使得调试更加容易

并不是所有的数据库都支持存储过程 但是存在许多很棒的实现 包括免费/开源的和非免费的 所以移植并不是一个问题 Oracle PostgreSQL和DB 都有类似的存储过程语言 并且有在线的社区很好地支持

存储过程工具很多 有像TOAD或TORA这样的编辑器 调试器和IDE 提供了编写 维护PL/SQL或pl/pgsql的强大的环境

lishixinzhi/Article/program/Java/hx/201311/25906

从 MySQL 57 开始,开发人员改变了 InnoDB 构建二级索引的方式,采用自下而上的方法,而不是早期版本中自上而下的方法了。在这篇文章中,我们将通过一个示例来说明如何构建 InnoDB 索引。最后,我将解释如何通过为 innodb_fill_factor 设置更合适的值。

索引构建过程

在有数据的表上构建索引,InnoDB 中有以下几个阶段:1读取阶段(从聚簇索引读取并构建二级索引条目)2合并排序阶段3插入阶段(将排序记录插入二级索引)在 56 版本之前,MySQL 通过一次插入一条记录来构建二级索引。这是一种“自上而下”的方法。搜索插入位置从树的根部(顶部)开始并达到叶页(底部)。该记录插入光标指向的叶页上。在查找插入位置和进行业面拆分和合并方面开销很大。从MySQL 57开始,添加索引期间的插入阶段使用“排序索引构建”,也称为“批量索引加载”。在这种方法中,索引是“自下而上”构建的。即叶页(底部)首先构建,然后非叶级别直到根(顶部)。

示例

在这些情况下使用排序的索引构建:

ALTER TABLE t1 ADD INDEX(or CREATE INDEX)

ALTER TABLE t1 ADD FULLTEXT INDEX

ALTER TABLE t1 ADD COLUMN, ALGORITHM = INPLACE

OPIMIZE t1

对于最后两个用例,ALTER 会创建一个中间表。中间表索引(主要和次要)使用“排序索引构建”构建。

算法

在 0 级别创建页,还要为此页创建一个游标

使用 0 级别处的游标插入页面,直到填满

页面填满后,创建一个兄弟页(不要插入到兄弟页)

为当前的整页创建节点指针(子页中的最小键,子页码),并将节点指针插入上一级(父页)

在较高级别,检查游标是否已定位。如果没有,请为该级别创建父页和游标

在父页插入节点指针

如果父页已填满,请重复步骤 3, 4, 5, 6

现在插入兄弟页并使游标指向兄弟页

在所有插入的末尾,每个级别的游标指向最右边的页。提交所有游标(意味着提交修改页面的迷你事务,释放所有锁存器)

为简单起见,上述算法跳过了有关压缩页和 BLOB(外部存储的 BLOB)处理的细节。

通过自下而上的方式构建索引

为简单起见,假设子页和非子页中允许的 最大记录数为 3

CREATE TABLE t1 (a INT PRIMARY KEY, b INT, c BLOB);

INSERT INTO t1 VALUES (1, 11, 'hello111');

INSERT INTO t1 VALUES (2, 22, 'hello222');

INSERT INTO t1 VALUES (3, 33, 'hello333');

INSERT INTO t1 VALUES (4, 44, 'hello444');

INSERT INTO t1 VALUES (5, 55, 'hello555');

INSERT INTO t1 VALUES (6, 66, 'hello666');

INSERT INTO t1 VALUES (7, 77, 'hello777');

INSERT INTO t1 VALUES (8, 88, 'hello888');

INSERT INTO t1 VALUES (9, 99, 'hello999');

INSERT INTO t1 VALUES (10, 1010, 'hello101010');

ALTER TABLE t1 ADD INDEX k1(b);

InnoDB 将主键字段追加到二级索引。二级索引 k1 的记录格式为(b, a)。在排序阶段完成后,记录为:

(11,1), (22,2), (33,3), (44,4), (55,5), (66,6), (77,7), (88,8), (99,9), (1010, 10)

初始插入阶段

让我们从记录 (11,1) 开始。

在 0 级别(叶级别)创建页

创建一个到页的游标

所有插入都将转到此页面,直到它填满了

箭头显示游标当前指向的位置。它目前位于第 5 页,下一个插入将转到此页面。

还有两个空闲插槽,因此插入记录 (22,2) 和 (33,3) 非常简单

对于下一条记录 (44,4),页码 5 已满(前面提到的假设最大记录数为 3)。这就是步骤。

页填充时的索引构建

创建一个兄弟页,页码 6

不要插入兄弟页

在游标处提交页面,即迷你事务提交,释放锁存器等

作为提交的一部分,创建节点指针并将其插入到 当前级别 + 1 的父页面中(即在 1 级别)

节点指针的格式 (子页面中的最小键,子页码) 。第 5 页的最小键是 (11,1) 。在父级别插入记录 ((11,1),5)。

1 级别的父页尚不存在,MySQL 创建页码 7 和指向页码 7 的游标。

将 ((11,1),5) 插入第 7 页

现在,返回到 0 级并创建从第 5 页到第 6 页的链接,反之亦然

0 级别的游标现在指向兄弟页,页码为 6

将 (44,4) 插入第 6 页

下一个插入 - (55,5) 和 (66,6) - 很简单,它们转到第 6 页。

插入记录 (77,7) 类似于 (44,4),除了父页面 (页面编号 7) 已经存在并且它有两个以上记录的空间。首先将节点指针 ((44,4),8) 插入第 7 页,然后将 (77,7) 记录到同级 8 页中。

插入记录 (88,8) 和 (99,9) 很简单,因为第 8 页有两个空闲插槽。

下一个插入 (1010,10) 。将节点指针 ((77,7),8) 插入 1级别的父页(页码 7)。

MySQL 在 0 级创建同级页码 9。将记录 (1010,10) 插入第 9 页并将光标更改为此页面。

以此类推。在上面的示例中,数据库在 0 级别提交到第 9 页,在 1 级别提交到第 7 页。

我们现在有了一个完整的 B+-tree 索引,它是自下至上构建的!

索引填充因子

全局变量 innodb_fill_factor 用于设置插入 B-tree 页中的空间量。默认值为 100,表示使用整个业面(不包括页眉)。聚簇索引具有 innodb_fill_factor=100 的免除项。 在这种情况下,聚簇索引也空间的 1 /16 保持空闲。即 625% 的空间用于未来的 DML。

值 80 意味着 MySQL 使用了 80% 的页空间填充,预留 20% 于未来的更新。如果 innodb_fill_factor=100 则没有剩余空间供未来插入二级索引。如果在添加索引后,期望表上有更多的 DML,则可能导致业面拆分并再次合并。在这种情况下,建议使用 80-90 之间的值。此变量还会影响使用 OPTIMIZE TABLE 和 ALTER TABLE DROP COLUMN, ALGOITHM=INPLACE 重新创建的索引。也不应该设置太低的值,例如低于 50。因为索引会占用浪费更多的磁盘空间,值较低时,索引中的页数较多,索引统计信息的采样可能不是最佳的。优化器可以选择具有次优统计信息的错误查询计划。

排序索引构建的优点

没有页面拆分(不包括压缩表)和合并

没有重复搜索插入位置

插入不会被重做记录(页分配除外),因此重做日志子系统的压力较小

缺点

ALTER 正在进行时,插入性能降低 Bug#82940,但在后续版本中计划修复。

lambda表达式只是一个简单的复数比较吧。根据存储过程根本没可比性。

你这个比就是一行代码跟一套代码比。

而且千万级数据库只是幌子吧,实际数据库反应速度跟查询结果的返回行数成正版。

比如你lambda表达式返回三千万数据库,存储过程返回十条数据。在量的层面上已经不一致了。

要比较当然在同一个层面上。

lambda表达式逻辑单一,能走索引这个是优势

存储过程一般逻辑比较复杂,IOPS和CPU占用资源会很高。但是能不修改程序的情况下进行逻辑更新这个是优势

根本就是视情况而定,并不存在可比性。

问题一:SQL 中存储过程怎么使用 sql存储过程及应用

一、简介:

存储过程(Stored Procedure), 是一组为了完成特定功能的SQL 语句,集经编译后

存储在数据库中,用户通过指定存储过程的名字并给出参数,如果该存储过程带有参数来执行

它,

在SQL Server 的系列版本中,存储过程分为两类:系统提供的存储过程和用户自定义存储过程

系统SP,主要存储master 数据库中,并以sp_为前缀并且系统存储过程主要是从系统表中获取

信息,从而为系统管理员管理SQL Server。用户自定义存储过程是由用户创建,并能完成

某一特定功能,如:查询用户所需数据信息的存储过程。

存储过程具有以下优点

1存储过程允许标准组件式编程(模块化设计)

存储过程在被创建以后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句,而

且数

据库专业人员可随时对存储过程进行修改,但对应用程序源代码毫无影响。因为应用程序源代

码只包含存

储过程的调用语句,从而极大地提高了程序的可移植性。

2存储过程能够实现快速的执行速度

如果某一 *** 作包含大量的Transaction-SQL 代码,,或分别被多次执行,那么存储过程要比批处理

执行速度快很多,因为存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进

行分析优

化,并给出最终被存在系统表中的执行计划,而批处理的Transaction-SQL 语句在每次运行时

都要进行

编译和优化,因此速度相对要慢一些。

3存储过程能够减少网络流量

对于同一个针对数据数据库对象的 *** 作,如查询修改,如果这一 *** 作所涉及到的Transaction-SQL

语句被组织成一存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调

用语句,否

则将是多条SQL 语句从而大大增加了网络流量降低网络负载。

4存储过程可被作为一种安全机制来充分利用

系统管理员通过,对执行某一存储过程的权限进行限制,从而能够实现对相应的数据访问权限的

制。

二、变量

@I

三、流程控制语句(if else | select case | while )

Select CASE 实例

DECLARE @iRet INT, @PKDisp VARCHAR(20)

SET @iRet = '1'

Select @iRet =

CASE

WHEN @PKDisp = '一' THEN 1

WHEN @PKDisp = '二' THEN 2

WHEN @PKDisp = '三' THEN 3

WHEN @PKDisp = '四' THEN 4

WHEN @PKDisp = '五' THEN 5

ELSE 100

END

四、存储过程格式

创建存储过程

Create Proc dbo存储过程名

存储过程参数

AS

执行语句

RETURN

执行存储过程

GO

/

-- 变量的声明,sql里面声明变量时必须在变量前加@符号

DECLARE @I INT

-- 变量的赋值,变量赋值时变量前必须加set

SET @I = 30

-- 声明多个变量

DECLARE @s varchar(10),@a INT

-- Sql 里if语句

IF 条件 BEGIN

执行语句

END

ELSE BEGIN

>>

问题二:为什么要使用存储过程? 几个去 IBM 面试的兄弟回来抱怨:去了好几个不同的 IBM项目组,几乎每个面试官问到数据库的时候都要问用没用过存储过程,烦人不?大家去面的程序员,又不是笔者认为,存储过程说白了就是一堆 SQL 的合并。中间加了点逻辑控制。但是存储过程处理比较复杂的业务时比较实用。比如说,一个复杂的数据 *** 作。如果你在前台处理的话。可能会涉及到多次数据库连接。但如果你用存储过程的话。就只有一次。从响应时间上来说有优势。也就是说存储过程可以给我们带来运行效率提高的好处。另外,程序容易出现 BUG数据量小的,或者和钱没关系的项目不用存储过程也可以正常运作。mysql 的存储过程还有待实际测试。如果是正式项目,建议你用 sqlserver 或 oracle的存储过程。数据与数据之间打交道的话,过程会比程序来的快的多。面试官问有没有用存储,实际上就是想知道前来面试的程序员到底做过数据量大的项目没。如果是培训出来的,或者小项目小公司出来的,对存储肯定接触的少了。所以,要想进大公司,没有丰富存储过程经验,是不行的。错。存储过程不仅仅适用于大型项目,对于中小型项目,使用存储过程也是非常有必要的。其威力和优势主要体现在:1存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般 SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。2当对数据库进行复杂 *** 作时(如对多个表进行Update,Insert,Query,Delete时),可将此复杂 *** 作用存储过程封装起来与数据库提供的事务处理结合一起使用。这些 *** 作,如果用程序来完成,就变成了一条条的 SQL语句,可能要多次连接数据库。而换成存储,只需要连接一次数据库就可以了。3存储过程可以重复使用,可减少数据库开发人员的工作量。4安全性高,可设定只有某此用户才具有对指定存储过程的使用权。 存储过程的缺点1:调试麻烦,但是用 PL/SQL Developer 调试很方便!弥补这个缺点。 2:移植问题,数据库端代码当然是与数据库相关的。但是如果是做工程型项目,基本不存在移植问题。 3:重新编译问题,因为后端代码是运行前编译的,如果带有引用关系的对象发生改变时,受影响的存储过程、包将需要重新编译(不过也可以设置成运行时刻自动编译)。4:如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的。维护起来更加麻烦!

问题三:oracle中的存储过程,有什么作用,以及怎么在代码中使用? 楼上也不知道从哪扒下来的,一看LZ就是初学,举点例子不行吗?

比如建立个测试表

create table test(id int,name varchar2(10),counts int); insert into test values (1,'张三',100);insert into test values (2,'李四',200); mit;

现在给你出个题目是

查询所有人加在一起的counts是多少

创建存储过程

create or replace p_test --创建存储过程,asv_counts int;--定义变量begin --开始select sum(counts) into v_counts from test;--将得到的结果放到变量里DBMS_OUTPUTPUT_LINE(v_counts);--将结果打印输出end;--结束

执行这种不带输入参数的

begin p_test;end;

然后你检查下结果

再给你创建一个带输入参数的

题目是,查询id为1的人名是什么

create or replace p_test1(v_id int)asv_name varchar2(10);beginselect name into v_name from test where id=v_id;DBMS_OUTPUTPUT_LINE(v_name);end;

执行时这样

beginp_test1(1);end;

第2个我没给你写注释,你看你自己应该能理解吧

补充一下,存储过程不一定只是执行查询,也可以做删除或者修改等sql语句,总体来说就是几个或N个sql语句的 ,来完成系统内某些特定的需求,这些需求可以是一个sql搞定的,也可以是多个sql组合的

问题四:SQL 存储过程建立和使用方法 Sql Server的存储过程是一个被命名的存储在服务器上的Transacation-Sql语句 ,是封装重复性工作的一种方法,它支持用户声明的变量、条件执行和其他强大的编程功能。 存储过程相对于其他的数据库访问方法有以下的优点: (1)重复使用。存储过程可以重复使用,从而可以减少数据库开发人员的工作量。 (2)提高性能。存储过程在创建的时候就进行了编译,将来使用的时候不用再重新编译。一般的SQL语句每执行一次就需要编译一次,所以使用存储过程提高了效率。 (3)减少网络流量。存储过程位于服务器上,调用的时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输的数据量。 (4)安全性。参数化的存储过程可以防止SQL注入式的攻击,而且可以将Grant、Deny以及Revoke权限应用于存储过程。 存储过程一共分为了三类:用户定义的存储过程、扩展存储过程以及系统存储过程。 其中,用户定义的存储过程又分为Transaction-SQL和CLR两种类型。 Transaction-SQL 存储过程是指保存的Transaction-SQL语句 ,可以接受和返回用户提供的参数。 CLR存储过程是指对Net Framework公共语言运行时(CLR)方法的引用,可以接受和返回用户提供的参数。他们在Net Framework程序集中是作为类的公共静态方法实现的。(本文就不作介绍了) 创建存储过程的语句如下:Code

CREATE { PROC | PROCEDURE } [schema_name] procedure_name [ ; number ]

[ { @parameter [ type_schema_name ] data_type }

[ VARYING ] [ = default ] [ [ OUT [ PUT ]

] [ ,n ]

[ WITH [ ,n ]

[ FOR REPLICATION ]

AS { [;][ n ] | }

[;]

::=

[ ENCRYPTION ]

[ REPILE ]

[ EXECUTE_AS_Clause ]

::=

{ [ BEGIN ] statements [ END ] }

::=

EXTERNAL NAME assembly_nameclass_namemethod_name [schema_name]: 代表的是存储过程所属的架构的名称 例如: Create Schema yangyang8848

Go

Create Proc yangyang8848AllGoods

As Select From Master_Goods

Go 执行:Exec AllGoods 发生错误。 执>>

问题五:数据库中的存储过程怎么用 啊!!求解 10分 关键字:procedure

例子:

SQL> create [or replace] procedure procedure_name is

begin

--开始执行

insert into test('10001','Visket');

end;

/

以上 *** 作就能为test表添加一条信息

执行存储过程procedure用的命令是exec

记住存储过程中,语句结尾一定要有分号

问题六:存储过程是多用还是少用? 做项目的时候我们有时候会面临一个选择,我们到底是应该多写存储过程还是少写存储过程了?这个问题的争论也是由来已久,在不同的公司以及不同的技术负责人那里往往会得到不同的答案。在实际项目中我们最后所采取的方式,往往不外乎以下三种方式。

第一种方式是要求所有数据库 *** 作不使用任何的存储过程,所有 *** 作都采用标准sql语句来完成,即便是一个动作需要完成多步数据库 *** 作,也不使用任何存储过程,而是在程序代码中采用事务的方式来完成;第二种方式就是就要求所有的数据库 *** 作都用存储过程封装起来,哪怕是一个最简单的insert *** 作。在程序代码看不到一行 sql语句,如果采用分工合作的方式,程序员甚至都可以不懂sql语法。第三种方式是一般相对简单的数据库 *** 作采用标准sql语句来完成,一些相对比较复杂的商务逻辑用存储过程来完成。

当然系统如果采用了hibernate或nhibernate之类的框架,不需要写sql语句的时候,我想还是应该属于第三种方式,因为在开发的时候hibernate框架允许我们在适当的时候,抛开其框架自己写存储过程和sql语句来完成数据库 *** 作。其实这三种方式都各有所长,也各有不足。

第一种方式是所有的数据库 *** 作都采用标准sql语句来完成的方式,在程序的执行效率上是肯定不如后面两种方式,系统如果是一个大型的ERP,这种方式就是绝对不可取的。因为在开发基本结束后,系统如果需要优化或者希望得到优化时,那对开发人员来说就是一件非常麻烦的事情了,因为优化的重点基本上都是集中数据库 *** 作上,开发人员所能做的就是一个个sql语句去检查,是不是还能进一步优化,尤其是一些相对比较复杂的查询语句是我们所检查的重点。分页显示就是一个典型的存储过程提高程序效率的例子。如果使用存储过程来进行分页 *** 作,就是利用存储过程从系统中提取我们所需要的记录集,分页的效率就大大提高了。反过来如果我们不用存储过程进行分页 *** 作,是利用sql语句的方式把所有记录集都读入内存中,然后再从内存中获取我们所需要的记录 ,这样分页效率自然就降低了。当然利用sql语句也能得到我们所需要的记录,而不是所有记录,但是那样麻烦多了,不在我们讨论范围之内。

这种方式另外还有一个不足之处,一个系统或一个项目总会或多或少地存在有一些容易变化而又复杂的商务逻辑,如果把这些复杂的商务逻辑封装到存储过程中,商务逻辑的变化都只涉及存储过程变化,而与程序代码不 ,那么不用存储过程太可惜了。

这种方式虽然有不足,但是一旦采用这种方式的话,我们如果对该项目进行数据库移植的时候,开发人员就会觉得当时的决策人是多么的伟大与英明。而且我们知道access和mysql的以前版本是不提供存储过程支持的,所有一些中小项目在这个方面的选择往往也是不得已而为之。不用存储过程有一个优点,调试代码的时候没有存储过程可是要方便很多很多的哦,所以在很多很多的项目中都是采用标准的sql语句而不使用任何的存储过程。这可是大多程序员用标准sql而不用存储过程的直接原因,说白了,就是嫌麻烦。

第二种方式是所有的数据库 *** 作全部采用存储过程封装的方式,如果采用这种方式,程序的执行效率相对要高,尤其面对在一些复杂的商务逻辑时候,不仅在效率方面有明显的提高,而且当商务逻辑发生变化时,我们开发人员做相应的修改的时候,往往都不用修改程序代码,仅仅修改存储过程就能满足系统变化了。

还有一个好处就是当我们开发好的一个系统后,如果发现一种模式或语言在某些方面难以满足需求时,我们就可以很快的用两外一种语言来重新开发,那个时候就非常方便了。比如在02年中科院下属的一个公司就用ASP开>>

问题七:在SQL中存储过程的一般语法是什么? sql server存储过程语法

存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令。

定义总是很抽象。存储过程其实就是能完成一定 *** 作的一组SQL语句,只不过这组语句是放在数据库中的(这里我们只谈SQL Server)。如果我们通过创建存储过程以及在ASP中调用存储过程,就可以避免将SQL语句同ASP代码混杂在一起。这样做的好处至少有三个:

第一、大大提高效率。存储过程本身的执行速度非常快,而且,调用存储过程可以大大减少同数据库的交互次数。

第二、提高安全性。假如将SQL语句混合在ASP代码中,一旦代码失密,同时也就意味着库结构失密。

第三、有利于SQL语句的重用。

在ASP中,一般通过mand对象调用存储过程,根据不同情况,本文也介绍其它调用方法。为了方便说明,根据存储过程的输入输出,作以下简单分类:

1 只返回单一记录集的存储过程

假设有以下存储过程(本文的目的不在于讲述T-SQL语法,所以存储过程只给出代码,不作说明):

/SP1/

CREATE PROCEDURE dbogetUserList

as

set nocount on

begin

select from dbo[userinfo]

end

go

以上存储过程取得userinfo表中的所有记录,返回一个记录集。通过mand对象调用该存储过程的ASP代码如下:

'通过mand对象调用存储过程

DIM Mym,MyRst

Set Mym = ServerCreateObject(ADODBmand)

MymActiveConnection = MyConStr 'MyConStr是数据库连接字串

MymmandText = getUserList '指定存储过程名

MymmandType = 4 '表明这是一个存储过程

MymPrepared = true '要求将SQL命令先行编译

Set MyRst = MymExecute

Set Mym = Nothing

存储哗程取得的记录集赋给MyRst,接下来,可以对MyRst进行 *** 作。

在以上代码中,mandType属性表明请求的类型,取值及说明如下:

-1 表明mandText参数的类型无法确定

1 表明mandText是一般的命令类型

2 表明mandText参数是一个存在的表名称

4 表明mandText参数是一个存储过程的名称

还可以通过Connection对象或Recordset对象调用存储过程,方法分别如下:

'通过Connection对象调用存储过程

DIM MyConn,MyRst

Set MyConn = ServerCreateObject(&qu>>

问题八:如何使用Oracle存储过程的一个简单例子 楼主您好

---创建表

create table TESTTABLE

(

id1 VARCHAR2(12),

name VARCHAR2(32)

)

select tid1,tname from TESTTABLE t

insert into TESTTABLE (ID1, NAME)

values ('1', 'zhangsan');

insert into TESTTABLE (ID1, NAME)

values ('2', 'lisi');

insert into TESTTABLE (ID1, NAME)

values ('3', 'wangwu');

insert into TESTTABLE (ID1, NAME)

values ('4', 'xiaoliu');

insert into TESTTABLE (ID1, NAME)

values ('5', 'laowu');

---创建存储过程

create or replace procedure test_count

as

v_total number(1);

begin

select count() into v_total from TESTTABLE;

DBMS_OUTPUTput_line('总人数:'||v_total);

end;

--准备

--线对scott解锁:alter user scott account unlock;

--应为存储过程是在scott用户下。还要给scott赋予密码

---alter user scott identified by tiger;

---去命令下执行

EXECUTE test_count;

----在ql/spl中的sql中执行

begin

-- Call the procedure

test_count;

end;

create or replace procedure TEST_LIST

AS

---是用游标

CURSOR test_cursor IS select tid1,tname from TESTTABLE t;

begin

for Test_record IN test_cursor loop---遍历游标,在打印出来

DBMS_OUTPUTput_line(Test_recordid1||Test_recordname);

END LOOP;

test_count;--同时执行另外一个存储过程(TEST_LIST中包含存储过程test_count)

end;

-----执行存储过程TEST_LIST

begin

TEST_LIST;

END;

---存储过程的参数

---IN 定义一个输入参数变量,用于传递参数给存储过程

--OUT 定义一个输出参数变量,用于从存储过程获取数据

---IN OUT 定义一个输入、输出参数变量,兼有以上两者的功能

>>

问题九:如何使用sql语句查看存储过程 --下面这条语句可以查看存储过程具体代码exec sp_helptext 存储过程名--下面这条语句查看数据库中有哪些存储过程select from sysobjects where type='P'

问题十:存储过程中怎么使用row 一般分为十种情况,每种语法各不相同: 1、 创建语法create proc | procedure pro_name [{@参数数据类型} [=默认值] [output], {@参数数据类型} [=默认值] [output], ]as SQL_statements2、 创建不带参数存储过程--创建存储过程if (exists (select from sysobjects where name = 'proc_get_student')) drop proc proc_get_studentgocreate proc proc_get_studentas select from student;--调用、执行存储过程exec proc_get_student;3、 修改存储过程--修改存储过程alter proc proc_get_studentasselect from student;4、 带参存储过程--带参存储过程if (object_id('proc_find_stu', 'P') is not null) drop proc proc_find_stugocreate proc proc_find_stu(@startId int, @endId int)as select from student where id between @startId and @endIdgoexec proc_find_stu 2, 4;5、 带通配符参数存储过程--带通配符参数存储过程if (object_id('proc_findStudentByName', 'P') is not null) drop proc proc_findStudentByNamegocreate proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')as select from student where name like @name and name like @nextName;goexec proc_findStudentByName;exec proc_findStudentByName '%o%', 't%';6、 带输出参数存储过程if (object_id('proc_getStudentRecord', 'P') is not null) drop proc proc_getStudentRecordgocreate proc proc_getStudentRecord( @id int, --默认输入参数 @name varchar(20) out, --输出参数 @age varchar(20) output--输入输出参数)as select @name = name, @age = age from student where id = @id and sex = @age;go-- declare @id int, @name varchar(20), @temp varchar(20)>>

以上就是关于什么是存储过程有什么优点全部的内容,包括:什么是存储过程有什么优点、Java数据库程序中的存储过程设计、Mysql Innodb存储引擎 select count 太慢,怎么优化等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/10152658.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-05
下一篇 2023-05-05

发表评论

登录后才能评论

评论列表(0条)

保存