Ⅰ oracle sql语法 ①中的:1代表什么;②中声明的变量类型是什么;③中的赋值语法是什么
1. 这是一个绑定变量的标准写法,:1可以理解为一个占位符。OLTP系统里面使用这种绑定变量的写法可以减少硬解析的次数,减少对数据字典以及Latch的使用,单个语句上提升的不大,但是对于整体性能有很大的提升。
2. 声明了一个number数组类型num_list,其最大存储number元素的个数为20。java里面类似于int[20]。
3. 声明变量v_id 类型为num_list,并且初始化变量v_id的第一、二个element为100,101。
Ⅱ java连接oracle数据库java.sql.SQLException:无效的列索引问题
java.sql.SQLException: 无效的列索引
无效的列索引
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:145)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:207)
atoracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:5328)
atoracle.jdbc.driver.OraclePreparedStatement.setString(OraclePreparedStatement.java:5320)
at untitled5.addreader1.validID(addreader1.java:128)
at untitled5.addreader1.jButton1_actionPerformed(addreader1.java:97)
at untitled5.addreader1_jButton1_actionAdapter.actionPerformed(addreader1.java:175)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
代码:String driverName = "oracle.jdbc.OracleDriver";
Driver driver = (Driver) Class.forName(driverName).newInstance();
//连接数据库
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:@LONG:1521:orcl", "sysman", "tongfang");
PreparedStatement pstmt = con.prepareStatement(
" insert into reader values(?)");
pstmt.setString(1, str1);
pstmt.setString(2,str2);
pstmt.setString(3,str3);
pstmt.setString(4,str4);
ResultSet res = pstmt.executeQuery();
Ⅲ Oracle面试题(基础篇)
Oracle面试题(基础篇)
Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。以下是关于Oracle面试题(基础篇),希望大家认真阅读!
1. Oracle跟SQL Server 2005的区别?
宏观上:
1). 最大的区别在于平台,oracle可以运行在不同的平台上,sql server只能运行在windows平台上,由于windows平台的稳定性和安全性影响了sql server的稳定性和安全性
2). oracle使用的脚本语言为PL-SQL,而sql server使用的脚本为T-SQL
微观上: 从数据类型,数据库的结构等等回答
2. 如何使用Oracle的游标?
1). oracle中的游标分为显示游标和隐式游标
2). 显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;隐式游标是在执行插入 (insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。
3). 显式游标的操作:打开游标、操作游标、关闭游标;PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它
3. Oracle中function和procere的区别?
1). 可以理解函数是存储过程的一种
2). 函数可以没有参数,但是一定需要一个返回值,存储过程可以没有参数,不需要返回值
3). 函数return返回值没有返回参数模式,存储过程通过out参数返回值, 如果需要返回多个参数则建议使用存储过程
4). 在sql数据操纵语句中只能调用函数而不能调用存储过程
4. Oracle的导入导出有几种方式,有何区别?
1). 使用oracle工具 exp/imp
2). 使用plsql相关工具
方法1. 导入/导出的是二进制的数据, 2.plsql导入/导出的是sql语句的文本文件
5. Oracle中有哪几种文件?
数据文件(一般后缀为.dbf或者.ora),日志文件(后缀名.log),控制文件(后缀名为.ctl)
6. 怎样优化Oracle数据库,有几种方式?
个人理解,数据库性能最关键的因素在于IO,因为操作内存是快速的,但是读写磁盘是速度很慢的,优化数据库最关键的问题在于减少磁盘的IO,就个人理解应该分为物理的和逻辑的优化, 物理的是指oracle产品本身的一些优化,逻辑优化是指应用程序级别的优化
物理优化的一些原则:
1). Oracle的运行环境(网络,硬件等)
2). 使用合适的优化器
3). 合理配置oracle实例参数
4). 建立合适的索引(减少IO)
5). 将索引数据和表数据分开在不同的表空间上(降低IO冲突)
6). 建立表分区,将数据分别存储在不同的分区上(以空间换取时间,减少IO)
逻辑上优化:
1). 可以对表进行逻辑分割,如中国移动用户表,可以根据手机尾数分成10个表,这样对性能会有一定的作用
2). Sql语句使用占位符语句,并且开发时候必须按照规定编写sql语句(如全部大写,全部小写等)oracle解析语句后会放置到共享池中
如: select * from Emp where name=? 这个语句只会在共享池中有一条,而如果是字符串的话,那就根据不同名字存在不同的语句,所以占位符效率较好
3). 数据库不仅仅是一个存储数据的地方,同样是一个编程的地方,一些耗时的操作,可以通过存储过程等在用户较少的情况下执行,从而错开系统使用的高峰时间,提高数据库性能
4). 尽量不使用*号,如select * from Emp,因为要转化为具体的列名是要查数据字典,比较耗时
5). 选择有效的表名
对于多表连接查询,可能oracle的优化器并不会优化到这个程度, oracle 中多表查询是根据FROM字句从右到左的数据进行的,那么最好右边的表(也就是基础表)选择数据较少的表,这样排序更快速,如果有link表(多对多中间表),那么将link表放最右边作为基础表,在默认情况下oracle会自动优化,但是如果配置了优化器的情况下,可能不会自动优化,所以平时最好能按照这个方式编写sql
6). Where字句 规则
Oracle 中Where字句时从右往左处理的,表之间的连接写在其他条件之前,能过滤掉非常多的数据的条件,放在where的末尾, 另外!=符号比较的列将不使用索引,列经过了计算(如变大写等)不会使用索引(需要建立起函数), is null、is not null等优化器不会使用索引
7). 使用Exits Not Exits 替代 In Not in
8). 合理使用事务,合理设置事务隔离性
数据库的数据操作比较消耗数据库资源的,尽量使用批量处理,以降低事务操作次数
7. Oracle中字符串用什么符号链接?
Oracle中使用 || 这个符号连接字符串 如 ‘abc’ || ‘d’
8. Oracle分区是怎样优化数据库的`?
Oracle的分区可以分为:列表分区、范围分区、散列分区、复合分区。
1). 增强可用性:如果表的一个分区由于系统故障而不能使用,表的其余好的分区仍可以使用;
2). 减少关闭时间:如果系统故障只影响表的一部份分区,那么只有这部份分区需要修复,可能比整个大表修复花的时间更少;
3). 维护轻松:如果需要得建表,独产管理每个公区比管理单个大表要轻松得多;
4). 均衡I/O:可以把表的不同分区分配到不同的磁盘来平衡I/O改善性能;
5). 改善性能:对大表的查询、增加、修改等操作可以分解到表的不同分区来并行执行,可使运行速度更快
6). 分区对用户透明,最终用户感觉不到分区的存在。
9. Oracle是怎样分页的?
Oracle中使用rownum来进行分页, 这个是效率最好的分页方法,hibernate也是使用rownum来进行oralce分页的
select * from
( select rownum r,a from tabName where rownum <= 20 )
where r > 10
10. Oralce怎样存储文件,能够存储哪些文件?
Oracle 能存储 clob、nclob、 blob、 bfile
Clob 可变长度的字符型数据,也就是其他数据库中提到的文本型数据类型
Nclob 可变字符类型的数据,不过其存储的是Unicode字符集的字符数据
Blob 可变长度的二进制数据
Bfile 数据库外面存储的可变二进制数据
11. Oracle中使用了索引的列,对该列进行where条件查询、分组、排序、使用聚集函数,哪些用到了索引?
均会使用索引, 值得注意的是复合索引(如在列A和列B上建立的索引)可能会有不同情况
12. 数据库怎样实现每隔30分钟备份一次?
通过操作系统的定时任务调用脚本导出数据库
13. Oracle中where条件查询和排序的性能比较?
Order by使用索引的条件极为严格,只有满足如下情况才可以使用索引,
1). order by中的列必须包含相同的索引并且索引顺序和排序顺序一致
2). 不能有null值的列
所以排序的性能往往并不高,所以建议尽量避免order by
14. 解释冷备份和热备份的不同点以及各自的优点?
冷备份发生在数据库已经正常关闭的情况下,将关键性文件拷贝到另外位置的一种说法
热备份是在数据库运行的情况下,采用归档方式备份数据的方法
冷备的优缺点:
1).是非常快速的备份方法(只需拷贝文件)
2).容易归档(简单拷贝即可)
3).容易恢复到某个时间点上(只需将文件再拷贝回去)
4).能与归档方法相结合,作数据库“最新状态”的恢复。
5).低度维护,高度安全。
冷备份不足:
1).单独使用时,只能提供到“某一时间点上”的恢复。
2).在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。
3).若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。
4).不能按表或按用户恢复。
热备的优缺点
1).可在表空间或数据文件级备份,备份时间短。
2).备份时数据库仍可使用。
3).可达到秒级恢复(恢复到某一时间点上)。
4).可对几乎所有数据库实体作恢复。
5).恢复是快速的,在大多数情况下在数据库仍工作时恢复。
热备份的不足是:
1).不能出错,否则后果严重。
2).若热备份不成功,所得结果不可用于时间点的恢复。
3).因难于维护,所以要特别仔细小心,不允许“以失败而告终”。
15. 解释data block , extent 和 segment的区别?
data block 数据块,是oracle最小的逻辑单位,通常oracle从磁盘读写的就是块
extent 区,是由若干个相邻的block组成
segment段,是有一组区组成
tablespace表空间,数据库中数据逻辑存储的地方,一个tablespace可以包含多个数据文件
;Ⅳ 如何使用占位符向oracle数据库中写日期类型的数据
windows和Linux都能执行
Oracle Call Interface(OCI)使用户可以访问 Oracle 10,Oracle9,Oracle8 和 Oracle7 数据库。支持将 PHP 变量与 Oracle 占位符(placeholder)绑定,具有完整的 LOB,FILE 和 ROWID 支持,以及允许使用用户提供的定义变量。
例子 1. 基本查询
<?php
$conn = oci_connect('hr', 'hr', 'orcl');
if (!$conn) {
$e = oci_error();
print htmlentities($e['message']);
exit;
}
$query = 'SELECT * FROM DEPARTMENTS';
$stid = oci_parse($conn, $query);
if (!$stid) {
$e = oci_error($conn);
print htmlentities($e['message']);
exit;
}
$r = oci_execute($stid, OCI_DEFAULT);
if(!$r) {
$e = oci_error($stid);
echo htmlentities($e['message']);
exit;
}
print '<table border="1">';
while($row = oci_fetch_array($stid, OCI_RETURN_NULLS)) {
print '<tr>';
foreach($row as $item) {
print '<td>'.($item?htmlentities($item):' ').'</td>';
}
print '</tr>';
}
print '</table>';
oci_close($conn);
?>
例子 2. 用绑定变量插入
<?php
// Before running, create the table:
// CREATE TABLE MYTABLE (mid NUMBER, myd VARCHAR2(20));
$conn = oci_connect('scott', 'tiger', 'orcl');
$query = 'INSERT INTO MYTABLE VALUES(:myid, :mydata)';
$stid = oci_parse($conn, $query);
$id = 60;
$data = 'Some data';
oci_bind_by_name($stid, ':myid', $id);
oci_bind_by_name($stid, ':mydata', $data);
$r = oci_execute($stid);
if($r)
print "One row inserted";
oci_close($conn);
?>
例子 3. 将数据插入到 CLOB 列中
<?php
// Before running, create the table:
// CREATE TABLE MYTABLE (mykey NUMBER, myclob CLOB);
$conn = oci_connect('scott', 'tiger', 'orcl');
$mykey = 12343; // arbitrary key for this example;
$sql = "INSERT INTO mytable (mykey, myclob)
VALUES (:mykey, EMPTY_CLOB())
RETURNING myclob INTO :myclob";
$stid = oci_parse($conn, $sql);
$clob = oci_new_descriptor($conn, OCI_D_LOB);
oci_bind_by_name($stid, ":mykey", $mykey, 5);
oci_bind_by_name($stid, ":myclob", $clob, -1, OCI_B_CLOB);
oci_execute($stid, OCI_DEFAULT);
$clob->save("A very long string");
oci_commit($conn);
// Fetching CLOB data
$query = 'SELECT myclob FROM mytable WHERE mykey = :mykey';
$stid = oci_parse ($conn, $query);
oci_bind_by_name($stid, ":mykey", $mykey, 5);
oci_execute($stid, OCI_DEFAULT);
print '<table border="1">';
while ($row = oci_fetch_array($stid, OCI_ASSOC)) {
$result = $row['MYCLOB']->load();
print '<tr><td>'.$result.'</td></tr>';
}
print '</table>';
?>
可以很容易地访问存储过程,就和从命令行访问一样。 例子 4. 使用存储过程
<?php
// by webmaster at remoterealty dot com
$sth = oci_parse($dbh, "begin sp_newaddress( :address_id, '$firstname',
'$lastname', '$company', '$address1', '$address2', '$city', '$state',
'$postalcode', '$country', :error_code );end;");
// This calls stored procere sp_newaddress, with :address_id being an
// in/out variable and :error_code being an out variable.
// Then you do the binding:
oci_bind_by_name($sth, ":address_id", $addr_id, 10);
oci_bind_by_name($sth, ":error_code", $errorcode, 10);
oci_execute($sth);
?>
连接处理
OCI8 扩展提供了 3 个不同函数来连接 Oracle。取决于用户来使用对自己的应用程序最合适的函数。本节的信息有助于用户作出合适的选择。
连接到 Oracle 服务器从所需的时间上来讲是个相当花费的操作。oci_pconnect() 函数使用了一个连接的持久缓冲区,可以被不同的脚本请求重复使用。这意味着通常在每个 PHP 进程(或 Apache 子进程)中只需要连接一次。
如果应用程序连接 Oracle 时对每个 web 用户都使用了不同的认证信息,则由 oci_pconnect() 使用的持久缓冲区就用处不大了,因为随着并发用户的增加,到某个程度后会由于要保持太多的空闲连接而对 Oracle 服务器的整体性能起到逆反的影响。如果应用程序是这样的架构,建议要么用 oci8.max_persistent 和 oci8.persistent_timeout 配置选项(此二者可以使用户控制持久连接缓冲区的大小和生命周期)来协调应用程序,要么用 oci_connect() 来连接。
oci_connect() 和 oci_pconnect() 都使用了一个连接缓冲区。如果在某个脚本中用同样的参数多次调用 oci_connect(),则第二个和之后的调用会返回已有的连接句柄。oci_connect() 使用的连接缓冲区会在脚本执行完毕后或者明确地关闭了连接句柄时被清空。oci_pconnect() 有相似的行为,不过其缓冲区独立地维持着并在不同请求之间都存活着。
要记住此缓冲特性,因为它使两个句柄没有在事务级隔离开来(事实上是同一个连接句柄,因此没有任何方式的隔离)。如果应用程序需要两个独立的,事务级隔离的连接,应该使用 oci_new_connect()。
oci_new_connect() 总是创建一个到 Oracle 服务器的新连接,不管其它连接是否已经存在。高流量的 web 应用应该避免使用 oci_new_connect(),尤其是在程序最忙的部分。
有关于它的其他函数:
目录
OCI-Collection->append -- 向 collection 增加单元
OCI-Collection->assign -- 从现有的另一个 collection 向 collection 赋值
OCI-Collection->assignElem -- 给 collection 中的单元赋值
OCI-Collection->free -- 释放关联于 collection 的对象的资源
OCI-Collection->getElem -- 返回单元的值
OCI-Collection->max -- 返回 collection 中单元的最大数目
OCI-Collection->size -- 返回 collection 中的单元数目
OCI-Collection->trim -- 从 collection 尾端开始删除单元
OCI-Lob->append -- Appends data from the large object to another large object
OCI-Lob->close -- 关闭 LOB 描述符
OCI-Lob->eof -- Tests for end-of-file on a large object's descriptor
OCI-Lob->erase -- Erases a specified portion of the internal LOB data
OCI-Lob->export -- 将 LOB 的内容导出到文件中
OCI-Lob->flush -- Flushes/writes buffer of the LOB to the server
OCI-Lob->free -- 释放与 LOB 描述符所关联的资源
OCI-Lob->getBuffering -- Returns current state of buffering for the large object
OCI-Lob->import -- 将数据从文件导入 LOB
OCI-Lob->load -- 返回大对象的内容
OCI-Lob->read -- Reads part of the large object
OCI-Lob->rewind -- Moves the internal pointer to the beginning of the large object
OCI-Lob->save -- 将数据保存到大对象中
OCI-Lob->seek -- Sets the internal pointer of the large object
OCI-Lob->setBuffering -- Changes current state of buffering for the large object
OCI-Lob->size -- Returns size of large object
OCI-Lob->tell -- Returns current position of internal pointer of large object
OCI-Lob->truncate -- Truncates large object
OCI-Lob->write -- Writes data to the large object
OCI-Lob->writeTemporary -- 写入一个临时的大对象
oci_bind_by_name -- 绑定一个 PHP 变量到一个 Oracle 位置标志符
oci_cancel -- 取消从游标读取数据
oci_close -- 关闭 Oracle 连接
oci_commit -- 提交未执行的事务处理
oci_connect -- 建立一个到 Oracle 服务器的连接
oci_define_by_name -- 在 SELECT 中使用 PHP 变量作为定义的步骤
oci_error -- 返回上一个错误
oci_execute -- 执行一条语句
oci_fetch_all -- 获取结果数据的所有行到一个数组
oci_fetch_array -- Returns the next row from the result data as an associative or numeric array, or both
oci_fetch_assoc -- Returns the next row from the result data as an associative array
oci_fetch_object -- Returns the next row from the result data as an object
oci_fetch_row -- Returns the next row from the result data as a numeric array
oci_fetch -- Fetches the next row into result-buffer
oci_field_is_null -- 检查字段是否为 NULL
oci_field_name -- 返回字段名
oci_field_precision -- 返回字段精度
oci_field_scale -- 返回字段范围
oci_field_size -- 返回字段大小
oci_field_type_raw -- 返回字段的原始 Oracle 数据类型
oci_field_type -- 返回字段的数据类型
oci_free_statement -- 释放关联于语句或游标的所有资源
oci_internal_debug -- 打开或关闭内部调试输出
oci_lob_ -- Copies large object
oci_lob_is_equal -- Compares two LOB/FILE locators for equality
oci_new_collection -- 分配新的 collection 对象
oci_new_connect -- 建定一个到 Oracle 服务器的新连接
oci_new_cursor -- 分配并返回一个新的游标(语句句柄)
oci_new_descriptor -- 初始化一个新的空 LOB 或 FILE 描述符
oci_num_fields -- 返回结果列的数目
oci_num_rows -- 返回语句执行后受影响的行数
oci_parse -- 配置 Oracle 语句预备执行
oci_password_change -- 修改 Oracle 用户的密码
oci_pconnect -- 使用一个持久连接连到 Oracle 数据库
oci_result -- 返回所取得行中字段的值
oci_rollback -- 回滚未提交的事务
oci_server_version -- 返回服务器版本信息
oci_set_prefetch -- 设置预提取行数
oci_statement_type -- 返回 OCI 语句的类型
ocibindbyname -- oci_bind_by_name() 的别名
ocicancel -- oci_cancel() 的别名
ocicloselob -- OCI-Lob->close 的别名
ocicollappend -- OCI-Collection->append 的别名
ocicollassign -- OCI-Collection->assign 的别名
ocicollassignelem -- OCI-Collection->assignElem 的别名
ocicollgetelem -- OCI-Collection->getElem 的别名
ocicollmax -- OCI-Collection->max 的别名
ocicollsize -- OCI-Collection->size 的别名
ocicolltrim -- OCI-Collection->trim 的别名
ocicolumnisnull -- oci_field_is_null() 的别名
ocicolumnname -- oci_field_name() 的别名
ocicolumnprecision -- oci_field_precision() 的别名
ocicolumnscale -- oci_field_scale() 的别名
ocicolumnsize -- oci_field_size() 的别名
ocicolumntype -- oci_field_type() 的别名
ocicolumntyperaw -- oci_field_type_raw() 的别名
ocicommit -- oci_commit() 的别名
ocidefinebyname -- oci_define_by_name() 的别名
ocierror -- oci_error() 的别名
ociexecute -- oci_execute() 的别名
ocifetch -- oci_fetch() 的别名
ocifetchinto -- 获取下一行到一个数组
ocifetchistatement -- oci_fetch_all() 的别名
ocifreecollection -- OCI-Collection->free 的别名
ocifreecursor -- oci_free_statement() 的别名
ocifreedesc -- OCI-Lob->free 的别名
ocifreestatement -- oci_free_statement() 的别名
ociinternaldebug -- oci_internal_debug() 的别名
ociloadlob -- OCI-Lob->load 的别名
ocilogoff -- oci_close() 的别名
ocilogon -- oci_connect() 的别名
ocinewcollection -- oci_new_collection() 的别名
ocinewcursor -- oci_new_cursor() 的别名
ocinewscriptor -- oci_new_descriptor() 的别名
ocinlogon -- oci_new_connect() 的别名
ocinumcols -- oci_num_fields() 的别名
ociparse -- oci_parse() 的别名
ociplogon -- oci_pconnect() 的别名
ociresult -- oci_result() 的别名
ocirollback -- oci_rollback() 别名
ocirowcount -- oci_num_rows() 的别名
ocisavelob -- OCI-Lob->save 的别名
ocisavelobfile -- OCI-Lob->import 的别名
ociserverversion -- oci_server_version() 的别名
ocisetprefetch -- oci_set_prefetch() 的别名
ocistatementtype -- oci_statement_type() 的别名
ociwritelobtofile -- OCI-Lob->export 的别名
ociwritetemporarylob -- OCI-Lob->writeTemporary 的别名
Ⅳ 在oracle sql语句里有没有if...else...的用法,请各位大侠给个例子看看,灰常感谢!!
oracle 中if ..else 可以再pl/sql 中使用,
如果是要在SQL语句中达到这种效果可以用case when ... then ...else ..end;
mysql数据库中CASE WHEN语句。
case when语句,用于计算条件列表并返回多个可能结果表达式之一。
CASE 具有两种格式:
简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。
CASE 搜索函数计算一组布尔表达式以确定结果。
两种格式都支持可选的 ELSE 参数。
语法
简单 CASE 函数:
复制代码 代码如下:
CASE input_expression
WHEN when_expression THEN result_expression
[ ...n ]
[
ELSE else_result_expression
END
CASE 搜索函数:
复制代码 代码如下:
CASE
WHEN Boolean_expression THEN result_expression
[ ...n ]
[
ELSE else_result_expression
END
参数
input_expression
是使用简单 CASE 格式时所计算的表达式。Input_expression 是任何有效的 Microsoft? SQL Server? 表达式。
WHEN when_expression
使用简单 CASE 格式时 input_expression 所比较的简单表达式。When_expression 是任意有效的 SQL
Server 表达式。Input_expression 和每个 when_expression 的数据类型必须相同,或者是隐性转换。
占位符,表明可以使用多个 WHEN when_expression THEN result_expression 子句或 WHEN Boolean_expression THEN result_expression 子句。
THEN result_expression
当 input_expression = when_expression 取值为 TRUE,或者 Boolean_expression 取值为 TRUE 时返回的表达式。
result expression 是任意有效的 SQL Server 表达式。
ELSE else_result_expression
当比较运算取值不为 TRUE 时返回的表达式。如果省略此参数并且比较运算取值不为 TRUE,CASE 将返回 NULL
值。Else_result_expression 是任意有效的 SQL Server 表达式。Else_result_expression
和所有 result_expression 的数据类型必须相同,或者必须是隐性转换。
WHEN Boolean_expression
使用 CASE 搜索格式时所计算的布尔表达式。Boolean_expression 是任意有效的布尔表达式。
结果类型
从 result_expressions 和可选 else_result_expression 的类型集合中返回最高的优先规则类型。有关更多信息,请参见数据类型的优先顺序。
结果值
简单 CASE 函数:
计算 input_expression,然后按指定顺序对每个 WHEN 子句的 input_expression = when_expression 进行计算。
返回第一个取值为 TRUE 的 (input_expression = when_expression) 的 result_expression。
如果没有取值为 TRUE 的 input_expression = when_expression,则当指定 ELSE 子句时 SQL Server 将返回 else_result_expression;若没有指定 ELSE 子句,则返回 NULL 值。
CASE 搜索函数:
按指定顺序为每个 WHEN 子句的 Boolean_expression 求值。
返回第一个取值为 TRUE 的 Boolean_expression 的 result_expression。
如果没有取值为 TRUE 的 Boolean_expression,则当指定 ELSE 子句时 SQL Server 将返回 else_result_expression;若没有指定 ELSE 子句,则返回 NULL 值。
下面分享一些mysql case when语句的例子。
A. 使用带有简单 CASE 函数的 SELECT 语句
在 SELECT 语句中,简单 CASE 函数仅检查是否相等,而不进行其它比较。
例子,使用 CASE 函数更改图书分类显示。
复制代码 代码如下:
USE pubs
GO
SELECT Category =
CASE type
WHEN 'popular_comp' THEN 'Popular Computing'
WHEN 'mod_cook' THEN 'Modern Cooking'
WHEN 'business' THEN 'Business'
WHEN 'psychology' THEN 'Psychology'
WHEN 'trad_cook' THEN 'Traditional Cooking'
ELSE 'Not yet categorized'
END,
CAST(title AS varchar(25)) AS 'Shortened Title',
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY type, price
COMPUTE AVG(price) BY type
GO
注释,后来我试了一下不让用category=。
我使用的代码为:
复制代码 代码如下:
SELECT
case gender
WHEN 1 THEN 'NAN'
WHEN 0 THEN 'NV'
end as gender
FROM
t_swidy_day_nutrient
结果集:
Category Shortened Title Price
------------------- ------------------------- --------------------------
Business You Can Combat Computer S 2.99
Business Cooking with Computers: S 11.95
Business The Busy Executive's Data 19.99
Business Straight Talk About Compu 19.99
avg
==========================
13.73
Category Shortened Title Price
------------------- ------------------------- --------------------------
Modern Cooking The Gourmet Microwave 2.99
Modern Cooking Silicon Valley Gastronomi 19.99
avg
==========================
11.49
Category Shortened Title Price
------------------- ------------------------- --------------------------
Popular Computing Secrets of Silicon Valley 20.00
Popular Computing But Is It User Friendly? 22.95
avg
==========================
21.48
Category Shortened Title Price
------------------- ------------------------- --------------------------
Psychology Life Without Fear 7.00
Psychology Emotional Security: A New 7.99
Psychology Is Anger the Enemy? 10.95
Psychology Prolonged Data Deprivatio 19.99
Psychology Computer Phobic AND Non-P 21.59
avg
==========================
13.50
Category Shortened Title Price
------------------- ------------------------- --------------------------
Traditional Cooking Fifty Years in Buckingham 11.95
Traditional Cooking Sushi, Anyone? 14.99
Traditional Cooking Onions, Leeks, and Garlic 20.95
avg
==========================
15.96
(21 row(s) affected)
B. 使用带有简单 CASE 函数和 CASE 搜索函数的
SELECT 语句
在 SELECT 语句中,CASE 搜索函数允许根据比较值在结果集内对值进行替换。
例子:根据图书的价格范围将价格(money 列)显示为文本注释。
复制代码 代码如下:
USE pubs
GO
SELECT 'Price Category' =
CASE
WHEN price IS NULL THEN 'Not yet priced'
WHEN price < 10 THEN 'Very Reasonable Title'
WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
ELSE 'Expensive book!'
END,
CAST(title AS varchar(20)) AS 'Shortened Title'
FROM titles
ORDER BY price
GO
结果集:
Price Category Shortened Title
--------------------- --------------------
Not yet priced Net Etiquette
Not yet priced The Psychology of Co
Very Reasonable Title The Gourmet Microwav
Very Reasonable Title You Can Combat Compu
Very Reasonable Title Life Without Fear
Very Reasonable Title Emotional Security:
Coffee Table Title Is Anger the Enemy?
Coffee Table Title Cooking with Compute
Coffee Table Title Fifty Years in Bucki
Coffee Table Title Sushi, Anyone?
Coffee Table Title Prolonged Data Depri
Coffee Table Title Silicon Valley Gastr
Coffee Table Title Straight Talk About
Coffee Table Title The Busy Executive's
Expensive book! Secrets of Silicon V
Expensive book! Onions, Leeks, and G
Expensive book! Computer Phobic And
Expensive book! But Is It User Frien
(18 row(s) affected)
C. 使用带有 SUBSTRING 和 SELECT 的 CASE 函数
例子,使用 CASE 和 THEN 生成一个有关作者、图书标识号和每个作者所着图书类型的列表。
首先,来看下 CASE 的语法。在一般的 SELECT 中,其语法如下:
复制代码 代码如下:
SELECT <myColumnSpec> =
CASE
WHEN <A> THEN <somethingA>
WHEN <B> THEN <somethingB>
ELSE <somethingE>
END
以上代码,需要用具体的参数代替尖括号中的内容。
甚至还可以组合这些选项,添加一个 ORDER BY 子句,例如:
复制代码 代码如下:
USE pubs
GO
SELECT
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END AS Range,
Title
FROM titles
GROUP BY
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END,
Title
ORDER BY
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END,
Title
GO
除了选择自定义字段之外,在很多情况下 CASE 都非常有用。
稍加深入,还可以得到以前认为不可能得到的分组排序结果集。
使用CASE WHEN进行字符串替换处理
在SELECT查询中使用CASE WHEN
复制代码 代码如下:
/*
mysql> SELECT Name, RatingID AS Rating,
-> CASE RatingID
-> WHEN 'R' THEN 'Under 17 requires an alt.'
-> WHEN 'X' THEN 'No one 17 and under.'
-> WHEN 'NR' THEN 'Use discretion when renting.'
-> ELSE 'OK to rent to minors.'
-> END AS Policy
-> FROM DVDs
-> ORDER BY Name;
+-----------+--------+------------------------------+
| Name | Rating | Policy |
+-----------+--------+------------------------------+
| Africa | PG | OK to rent to minors. |
| Amadeus | PG | OK to rent to minors. |
| Christmas | NR | Use discretion when renting. |
| Doc | G | OK to rent to minors. |
| Falcon | NR | Use discretion when renting. |
| Mash | R | Under 17 requires an alt. |
| Show | NR | Use discretion when renting. |
| View | NR | Use discretion when renting. |
+-----------+--------+------------------------------+
8 rows in set (0.01 sec)
*/
Drop table DVDs;
CREATE TABLE DVDs (
ID SMALLINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Name VARCHAR(60) NOT NULL,
NumDisks TINYINT NOT NULL DEFAULT 1,
RatingID VARCHAR(4) NOT NULL,
StatID CHAR(3) NOT NULL
)
ENGINE=INNODB;
INSERT INTO DVDs (Name, NumDisks, RatingID, StatID)
VALUES ('Christmas', 1, 'NR', 's1'),
('Doc', 1, 'G', 's2'),
('Africa', 1, 'PG', 's1'),
('Falcon', 1, 'NR', 's2'),
('Amadeus', 1, 'PG', 's2'),
('Show', 2, 'NR', 's2'),
('View', 1, 'NR', 's1'),
('Mash', 2, 'R', 's2');
SELECT Name, RatingID AS Rating,
CASE RatingID
WHEN 'R' THEN 'Under 17 requires an alt.'
WHEN 'X' THEN 'No one 17 and under.'
WHEN 'NR' THEN 'Use discretion when renting.'
ELSE 'OK to rent to minors.'
END AS Policy
FROM DVDs
ORDER BY Name;
Ⅵ 如何调整oracle中的sql语句输入的最大长度
Oracle SQL 语句in长度不得超过1000
IN 子句中的LIST个数最长为1000,超过该数目将报错,这里可转用一个临时表来解决;CREATE TRIGGER语句文本的字符长度不能超过32KB(触发器中不能使用LONG, LONG RAW 类型;触发器内可以参照LOB 类型列的列值,但不能通过 :NEW 修改LOB列中的数据;)顺便说一下,触发器中的PARENT关键字,只在嵌套表触发器中有效,11G以前,DBMS_SQL对输入的SQL长度不能超过32K,原因是输入参数只能是VARCHAR2类型,11G后,可以用CLOB作为输入参数,则取消了这个限制一个PL/SQL的包、过程、函数、触发器的大小,在UNIX上最大是64K,而WINDOWS则是32K大小(32K这个应该不准,看下面的测试)SQL语句可以有多长?(网友说)ORACLE文档说是64K,实际受一些工具的限制会较这个值低,但网友测试发现可以很长,甚至超过1M(我测试过 170K的都没问题)。具体多长,10G也未说明,只是与很多环境有关:数据库配置,磁盘空间,内存多少。。。
PL/SQL中,表达式/SQL本身的长度是可以达到比较长的长度(50K)左右,如:v_str:=:new.f1||:ndw.f2。。。 ; select :new.f1||:new.f2。。。 into v_str from al; 另外发现,如果这样写:v_str := ‘a’||’b’||。。。则允许的表达式长度将大大的减少。如果表达式/SQL过长,超过了一个ORACLE包/过程允许的最大程序长度,则在编译时报 pls-123:program too large错误,这是pl/sql编译器本身的限制造成的,即表达式/SQL的长度在PL/SQL中受限于包/过程的最大大小=================================================Oracle Sql语句长度限制问题及解决
最近在写Sql语句时,碰到两个问题:
1)ORA-01795: maximum number of expressions in a list is 1000起因:写出了这样的sql语句:SELECT PALLET_ID,BOX_ID,STATUS FROM SD_CURRENT_BOX WHERE PALLET_ID IN('"+pallets+"');其中的pallets是有很多个pallet_id组合成的字符串。
分析:很显然,根据错误提示可以知道:in 中items的限制 1000个。
解决:用子查询来代替pallets长字串。
2)ORA-01704: string literal too long
起因:写出了这样的Sql语句:UPDATE PDM_MEMBERLIST SET MEMBERS='<Project> ... 此处略去n多串 <ProjectID>'.
分析:数据库设计MEMBERS字段为xmltype格式,数据存储时候,是以字符串的形式存储。这样在xml数据量大的时候,造成sql语句过长,尝过2k的限制。
解决:参数化sql语句。
==================================================参数化sql语句----防止sql注入攻击(下)
上一篇写的sql注入的基本原理,本来要接着写这篇的,但是由于时间的原因一直没有写成,今天是五一假期,总算是能抽空写写了。
作为一个程序员,防范sql注入的第一线是由我们来守护的,只要我们在程序中留少许的漏洞,就会给程序增强安全特性。所以我们要做的是要写安全的程序,防止sql注入在程序体现在不要拼接sql字符串,一定要参数化sql或者写存储过程,这里就说说简单的参数化sql吧。
例子中用c#和Oracle实现,Java中或者其他数据库中的实现也是类似的。
using System.Data.OracleClient;//引入oracle操作包//定义DML语句
string strSQL = @"select user.name from user where user.name =:userName";//上句中的:userName就是sql语句中参数的占位符,也就是说在数据库服务器中执行这条sql语句的时候这个占位符要被其他东西替换掉,到底用什么东西替换呢,接着往下看OracleParameter[] param = {
new OracleParameter(":userName",txtName);}//这里定义一个参数的数组,里面可以写入多个sql参数,咱们的这里只有一个,所以就写入一个参数,这里讲占位符和他的替换也就是参数值对应起来了,txtName就是占位符的替换值,他是用户界面中用户输入的值,就是他可能含有注入攻击的字符,这下数据库服务器知道用什么东西替换占位符了。
定义好sql语句和参数后就是执行了,执行的时候需要同时将sql语句和参数传入,这样用户输入的带有非法字符的字符串在数据库会当作参数处理,而不会当作sql语句和数据库自己的字符混乱,防止了注入攻击。
OracleCommandcmd = new OracleCommand();
cmd.CommandText= strSQL;//定义oracle命令的文本内容for(oracleParameter p in param)//将参数传入{
cmd.Parameters.Add(p);
}
cmd.ExecuteNonQuery();//执行命令
上面基本上是一个完整的参数化sql,不同的数据库服务器sql语句中参数的占位符不同,上面用的是oracle,参数占位符是冒号(:)加名字,在sqlserver中是用@符号加名字作为占位符,而在MySQL中用问号(?)加名字来作为参数占位符,不同的数据库中参数的表示符号不一样,这个需要注意。
防止sql注入攻击(上)
Sql注入是一种入门极低破坏极大的攻击方式。如果sql是用字符串拼接出来的话,那么肯定会被注入攻击,前段时间还传出了某国外大型社交网站被SQL注入攻击。
Sql注入攻击的方式,来这里看的同志们应该很清楚了,就是在拼接字符串的时候,如果输入的是带单引号的,那么输入laf'or 1='1'--这样就会逃避条件检查,后面要是再跟一些shutdown,delete之类的条件,那么损失基本算是毁灭性的了。前几天单位开发的过程中我发现几乎大家都不重视安全,一个写代码的人不注意安全只注意实现那么写出来的代码在攻击者眼前基本就是一个没有穿衣服的美女。
下面是我一个开发人员的一些经验,主要用来防止sql注入。
1、首先对运行sql的用户赋予最小权限,这个理论也是安全领域的最小特权理论,运行一个程序一定要用最小特权运行,所以不要给用户服务DBA的权限,限制要权限之后可以防止一些毁灭性的攻击,即使攻入了也不会shutdown修改表之类的。
2、一定不要使用字符串拼接的方式构造sql,必须使用参数化sql,存储过程可以看作是参数sql,简单的就直接构造参数化sql,复杂的就写存储过程,不过存储过程中一定不要用字符串,我看有人在存储过程用字符串,这样还是不能避免被攻击,并且在调试的时候非常麻烦。
3、严把输入关,系统肯定是用来交互的,所有用户输入的这一关一定要把好,可以利用各种方式来检验用户的输入,让输入都是合法的;可以设敏感字符不让用户输入,这个虽然不是很友好,不过对与安全有保证。在验证的是可以用正则表达式或者程序验证,不管用什么方式只要把敏感字符和可疑字符拒之门外那么就无法攻击了,不过限制输入还是有缺陷,在安全理论方面,只能确定合法,不能确定不合法,比如你在界面限制了合法的,那么剩余的都是不合法的,这时候输入的肯定全部是合法的,如果你限制的是非法的,可是你能确保你限制的全是非法的?如果某一天发现一个非法的不再你限制之内那么你就会被攻击。
4、做好自己的检验和测试工作,自己可以进行sql注入攻击,利用工具检验。
5、一定要养成具有安全意识的程序员,时刻想着安全。
这几条之中最重要的是1和2,权限限制一定要注意,不然会死的很惨的,第二就是程序员的习惯了,一定要用参数化sql和数据库交互。