Working with LOBs in Oracle and PHP
原文链接:http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html
Working with LOBs in Oracle and PHP Hitting the 4,000-byte limit? Enter LOBs...
Working with Oracle types like VARCHAR2 is fine, but what if you need to be able to store more than its 4,000-byte limit in one go? For this task, you need one of Oracle's Long Object (LOB) types, which in turn requires that you learn how to use the PHP API for working with LOBs. That in itself can be daunting for those unfamiliar with it. In this "Oracle+PHP Cookbook" HowTo, you will learn the available LOB types and issues related to them, then explore examples of common LOB operations in PHP. Long Objects in Oracle Oracle provides the following LOB types:
A further subcategory of LOB is the temporary LOB, which can be either a BLOB, CLOB, or NCLOB but is stored in the temporary tablespace until you free it. Note that older versions of Oracle provided the LONG and LONG RAW types for character and binary data, respectively. With Oracle9ithese were deprecated in favor of LOBs. LOB storage. For the BLOB, CLOB, and NCLOB types, Oracle Database 10g is capable of storing up to 128TB in a single value, depending on your database block size and the "chunk" setting, defined for the LOB. A LOB itself comprises two elements: the LOB content and the LOB locator, which is a "pointer" to the LOB content. This separation is required to allow Oracle to store and manage LOBs efficiently and it is reflected in the PHP APIs you use to INSERT, UPDATE, andSELECT LOBs (see below). For the internal LOB types (i.e. not BFILEs) Oracle will store the content of the LOB "in-line" in the table, with the rest of the row, if the size of the LOB is less than 4KB. LOBs larger than 4KB are stored "out-of-line," by default in the table's tablespace. This approach allows small LOBs to be retrieved quickly while, for large LOBs, access times will be slower but overall performance, when scanning the table, is preserved. There are further options for LOB storage and access—such as memory caching and buffering—which may improve performance, depending on the specifics of your application. For further information see the LOB Performance Guidelines and the Oracle Database Application Developer's Guide - Large Objects in the Oracle documentation. Restrictions on LOBs. A number of restrictions apply to the use of LOB types, the most important being their use in SQL statements. You cannot use a LOB type in any of the following queries. SELECT DISTINCT <lob_type> It is also illegal to use a LOB type column for table joins, UNION, INTERSECTION, and MINUS statements. Further restrictions apply to other aspects of the use of LOBs, such as you cannot use LOB as a primary key column. Again, seeOracle Database Application Developer's Guide - Large Objects for details. CLOBs and Character Sets The default character set for your database is defined by the parameter NLS_CHARACTERSET and text placed in a CLOB is expected to be encoded using this character set. Use this SQL to determine your databases character set encoding: SELECT value FROM nls_database_parameters WHERE parameter = 'NLS_CHARACTERSET' Given lack of support for NCLOBs in PHP, you may want to consider using Unicode encoding as the database character, such as UTF-8, which can be done (given sufficient privileges) using the statement: ALTER DATABASE CHARACTER SET UTF8 Note: do not attempt this without understanding the impact, especially if you have existing data or application code using a different character set. See the Oracle Globalization Support Guide and An Overview on Globalizing Oracle PHP Applications for more information. Working with LOBs The discussion here will focus on PHP's OCI8 extension. It's also worth noting that Oracle provides the DBMS_LOB package, containing parallel procedures and functions for working with LOBs using PL/SQL. The PHP OCI8 extension registers a PHP class called "OCI-Lob" in the global PHP namespace. When you execute a SELECTstatement, for example, where one of columns is a LOB type, PHP will bind this automatically to an OCI-Lob object instance. Once you have a reference to an OCI-Lob object, you can then call methods like load()and save()to access or modify the contents of the LOB. The available OCI-Lob methods will depend on your PHP version, PHP5 in particular having gained methods like read(), seek(), and append(). The PHP Manual is a little unclear, in this case, on the version numbers so if in doubt you can verify using the following script. <?php On my system, running PHP 5.0.5, I get the following list of methods: OCI-Lob::load() In practice, the PHP 4.x OCI8 extension supports reading or writing of complete LOBs only, which is the most common use case in a Web application. PHP5 extends this to allow reading and writing of "chunks" of a LOB as well as supporting LOB buffering with the methods setBuffering()and getBuffering(). PHP5 also provides the stand-alone functions oci_lob_is_equal()andoci_lob_copy(). The examples here will use the new PHP5 OCI function names (e.g. oci_parseinstead of OCIParse). Examples use the following sequence and table: CREATE SEQUENCE mylobs_id_seq Note that most of the examples here use CLOBs but the same logic can be applied almost exactly to BLOBs as well. Inserting a LOB To INSERT an internal LOB, you first need to initialize the LOB using the respective Oracle EMPTY_BLOB or EMPTY_CLOB functions—you cannot update a LOB that contains a NULL value. Once initialized, you then bind the column to a PHP OCI-Lob object and update the LOB content via the object's save() method. The following script provides an example, returning the LOB type from the INSERT query: <?php Notice how this example uses a transaction, instructing oci_executewith OCI_DEFAULT constant to wait for an oci_commitor anoci_rollback. This is important as I have two stages taking place in the INSERT—first create the row and second update the LOB. Note that if I was working with a BLOB type, the only change needed (assuming a BLOB column) is to the oci_bind_by_namecall: oci_bind_by_name($stmt, ":mylob_loc", $myLOB, -1, OCI_B_BLOB); Alternatively, you can bind a string directly without specifying a LOB type; <?php This approach simplifies the code significantly and is suitable when the data your want to write to the LOB is relatively small. In contrast, if you wished to stream the contents of the large file into a LOB, you might loop through the contents of the file callingwrite()and flush()on the PHP LOB object to write smaller chunks rather than having the entire file held in memory at a single instance. Selecting a LOB When a SELECT query contains a LOB column, PHP will automatically bind the column to an OCI-Lob object. For example: <?php This can be further simplified using the OCI_RETURN_LOBS constant, used with oci_fetch_array(), instructing it to replace LOB objects with their values: while ( $row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_LOBS) ) { Updating a LOB To UPDATE a LOB, it's also possible to use the "RETURNING" command in the SQL, as with the above INSERT example, but a simpler approach is to SELECT ... FOR UPDATE: <?php As with the INSERT, I need to perform the UPDATE using a transaction. An important additional step is the call to truncate(). When updating a LOB with save(), it will replace the contents of the LOB beginning from the start up to the length of the new data. That means older content (if it was longer than the new content) may still be left in the LOB. For PHP 4.x, where truncate() is unavailable, the following alternative solution uses Oracle's EMPTY_CLOB() function to erase any existing contents in the LOB before saving new data to it. $sql = "UPDATE Working with BFILES When using the BFILE type, INSERTs and UPDATEs mean telling Oracle where the file is located within the filesystem of the database server (which may not be the same machine as the Web server), rather than passing the file content. Using a SELECT statement, you can read the contents of the BFILE through Oracle, should you so desire, or call functions and procedures from the DBMS_LOBpackage to get information about the file. The main advantage of BFILEs is being able to access the original files directly from the filesystem while still being able to locate files using SQL. This means, for example, images can be served directly by the Web server while I can keep track of the relationship between the table containing the BFILES and, say, a "users" table, telling me who uploaded the files. As an example, I first need to update the table schema used above; ALTER TABLE mylobs ADD( mybfile BFILE ) Next I need to register a directory alias with Oracle (this requires administrative privileges) and grant permissions to read it: CREATE DIRECTORY IMAGES_DIR AS '/home/harryf/public_html/images' I can now INSERT some BFILE names like: <?php If I need to, I can read the BFILE content through Oracle using the same approach as above where I selected CLOBs. Alternatively, if I need to get the filenames back so I can access them directly from the filesystem, I can call the DBMS_LOB.FILEGETNAME procedure like: <?php Furthermore, you can use the DBMS_LOB.FILEEXISTS function to discover which files have been deleted via the operating system but are still referenced in the database. Conclusion In this HowTo you have been introduced to the different types of LOBs available in Oracle Database 10g and hopefully now understand their role in allowing large data entities to be stored efficiently in the database. You have also learned how to work with LOBs using PHP's OCI8 API, covering the common use cases you will encounter while developing with Oracle and PHP. |
Working with LOBs in Oracle and PHP的更多相关文章
- php 操作 oracle lob 数据
http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html Working with LOBs in Oracle and P ...
- LOBs and ORA-01555 troubleshooting (Doc ID 846079.1)
LOBs and ORA-01555 troubleshooting (Doc ID 846079.1) APPLIES TO: Oracle Database Cloud Schema Servic ...
- 基本类型(2):oracle中有4个大对象(lobs)类型可用,分别是blob,clob,bfile,nclob。
1)blob:二进制lob,为二进制数据,最长可达4GB,存贮在数据库中. 2)clob:字符lob,字符数据,最长可以达到4GB,存贮在数据库中. 3)bfile:二进制文件;存贮在数据库之外的只读 ...
- Oracle数据库shutdown immediate被hang住的几个原因
实验操作环境: 操作系统:Red Hat Enterprise Linux ES release 4 (Nahant Update 6) ...
- 数据导入导出Oracle数据库
临近春节,接到了一个导入数据的任务,在Linux客户端中的数据有50G,大约3亿3千万行: 刚开始很天真,把原始的txt/csv文件用sh脚本转化成了oralce 的insert into 语句,然后 ...
- Oracle 12c In Memory Option初探
前情提要: Oracle OpenWorld 2013中Larry Ellison爆料的Oracle新特性:Oracle In Memory Database Option 1. 这个新特性将随着12 ...
- Oracle命名规范
1.编写目的 使用统一的命名和编码规范,使数据库命名及编码风格标准化,以便于阅读.理解和继承. 2.适用范围 本规范适用于公司范围内所有以ORACLE作为后台数据库的应用系统和项目开发工作. 3.对象 ...
- Oracle中可以nologging执行的操作
redo重做日志是Oracle数据库恢复(recovery)的基础:但在很多情况下可以通过禁用重做日志的产生来加速SQL语句的完成,也就是我们所说的可nologging化的操作,这些操作大多是或串行的 ...
- Oracle优化 -- 关于Database Buffer Cache相关参数DB_CACHE_SIZE的优化设置
select size_for_estimate, buffers_for_estimate ,ESTD_PHYSICAL_READ_factor,ESTD_PHYSICAL_READS from v ...
随机推荐
- 一月份实现Adb小程序
As Brian said: According to a post on xda-developers, you can enable ADB over WiFi from the device w ...
- 19.python的编码问题
在正式说明之前,先给大家一个参考资料:戳这里 文章的内容参考了这篇资料,并加以总结,为了避免我总结的不够完善,或者说出现什么错误的地方,有疑问的地方大家可以看看上面那篇文章. 以下说明是针对于pyth ...
- Bash美化
首先声明下,这些美化方式都不是我自己想的,而是多个牛人的方法. 第一:简单点 这个方法来自于:http://www.vimer.cn/?p=1554 没有美化前是这样,鼠标光标在很右边: 在.bash ...
- C开发 中原子性操作 , 除了快什么都不剩下了
题外话 今天,听歌曲听到一首缅怀迈克尔·杰克逊的歌曲 如下: http://music.163.com/#/song?id=1696048 Breaking News 每次听迈克尔 音乐,特别有战斗 ...
- word超链接显示HYPERLINK
在word中编辑超链接后显示的并不是正常的超链接 正常的超连接 非正常显示 解决办法: 文件---选项----高级,如下图 将“显示域代码而非值域”前面的勾去掉.
- js的reduce方法,改变头等函数
头等函数:把编程变成了类似搭积木的方式编码,可以使用很少的代码,实现强大的功能函数. eg: getTotal:数组的求和运算. var myArray = [1,2,3,4]; var add = ...
- 使用angular封装echarts
Echarts是一个开源的图表组件,图表比较丰富,工作中需要用到它来搭建一个数据展示系统.但是系统原有的框架是基于angular的,而echarts是基于原生js的,如果直接使用的话就丢失了angul ...
- [quote ]ffmpeg, gstreamer, Raspberry Pi, Windows Desktop streaming
[quote ]ffmpeg, gstreamer, Raspberry Pi, Windows Desktop streaming http://blog.pi3g.com/2013/08/ffmp ...
- cocos2dx中的场景和使用方法
1.一个游戏中有且只有一个导演,但是至少有一个场景 2.场景是游戏元素节点数的根节点,也可以理解为该场景下的渲染树的根节点 3.场景是一个容器,包含了该场景下的所有游戏元素,比如层,精灵 4.场景是导 ...
- C++中的运算符重载注意事项
1.C++中的运算符重载的方式有三种: a.类成员函数重载 b.友元函数重载 c.普通函数重载 注意: a.我们主要使用的方式主要是用:类成员函数和友元函数来实现运算符的重载. b.其实用普通函数理论 ...