一、在oracle项目开发中越到问题:

在利用ODP向oracle中插入数据时,如果这样写:
  insert into clobTable (id, story) values(1,'....'); 其中story为clob类型
  如果story的长度大于2000字节,直接插入将出现 ORA-01704:文字字符串过长 的错误。
解决方案:
      方案一、利用参数
  insert into clobTable (id, story) values(1,:story);
  OracleParameter param = new OracleParameter("story", OracleDbType.Clob);
  param.Direction = ParameterDirection.Input;
  param.Value = str;
  cmd.Parameters.Add(param);
      方案二、利用存储过程
  这个就不用说了,写个存储过程,把参数传入即可。

二、解决方法

oracle 中,如下操作:

insert into table values(a,3,'一个长文章');

ORA-01704: 文字字符串过长!

虽然在表中已经是clob字段,足够存储4G的内容,但是如果存的是特别长的字符串,超过4000就会报错。

解决方法:

方法一:就写个存储过程,然后用参数传过去就没问题了。

declare

v_clob clob :='一个长文章';

begin
  insert into table values(a,3,:clob);
 end;

这样就可以插进去了,所以我觉得应该是隐式转换,oracle默认把字符串 转换成 varchar2 类型,
 而这个字符串的长度,又比4000大 所以会报ora-01704错误.

真实环境用的存储过程:

CREATE OR REPLACE PROCEDURE "BAI"."LOGMNRTXT" (tab1 in varchar2,scns in number,timestamps in varchar2,seg_owner in varchar2,
table_name in varchar2,session_info in varchar2,sql_redo in clob,ssession in varchar2,serial in varchar2,operation in varchar2) is

str varchar(1000);
 --注意tab1必须要更改,发现原来的logmnr_contents20140524中的sql_redo为varchar,需要改成clob
begin

str:= 'insert into '||tab1||' values(:1,:2,:3,:4,:5,:6,:7,:8,:9)';
   execute immediate str using scns,to_date(timestamps,'yyyy-MM-dd hh24:mi:ss'),seg_owner,table_name,session_info,sql_redo,ssession,serial,operation;
end logmnrtxt;
/

方法二:很复杂,其实没必要这么用,主要是为了学习高级的存储过程写法

创建存储过程:
CREATE OR REPLACE PROCEDURE p_In_Clob(pId IN NUMBER,outVar IN VARCHAR2)
IS
  text_Var  CLOB;
  amount_Var  NUMBER;
  offset_Var  NUMBER;
BEGIN
  INSERT INTO test VALUES(pId,empty_clob());
  SELECT text INTO text_var FROM test
    WHERE id=pId;
  amount_var:=LENGTH(outVar);
  offset_var:=1;
  DBMS_LOB.WRITE(text_Var,amount_Var,offset_Var,outVar);
  COMMIT;
END p_In_Clob;

调用存储过程:
begin
  p_In_Clob(1,'...');
end;

三、oracle 存储过程使用动态sql

Oracle存储过程使用动态SQL 有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。试验步骤如下:

1. DDL和DML (注意DDL中可以用拼接字符串的方法用来create table或drop table,在DML中,类似于insert则不可以直接用execute immediate中直接拼接的方法,必须用using传递参数)

     /*** DDL ***/
begin
EXECUTE IMMEDIATE 'drop table temp_1';
EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))';
end; /*** DML ***/
declare
v_1 varchar2(8);
v_2 varchar2(10);
str varchar2(50);
begin
v_1:='测试人员'; --这里的v_1,v_2可以是直接存储过程中传过来的参数
v_2:='北京';
str := 'INSERT INTO test (name ,address) VALUES (:1, :2)';
EXECUTE IMMEDIATE str USING v_1, v_2;
commit;
end;

2. 返回单条结果

例1:

     declare
str varchar2(500);
c_1 varchar2(10);
r_1 test%rowtype;
begin
c_1:='测试人员';
str:='select * from test where name=:c WHERE ROWNUM=1';
execute immediate str into r_1 using c_1;
DBMS_OUTPUT.PUT_LINE(R_1.NAME||R_1.ADDRESS);
end ;

例2:

     declare
v_col_name varchar2(30) := 'name'; --字段名 name 用变量来表示
v_user_name varchar2(30); --用户名称
v_user_age integer; --用户年龄
v_sql_str varchar2(500); --动态 SQL 语句
begin
v_sql_str := 'select '||v_col_name||',age from users --字段名后面不能紧随 into 到变量了
where age between :start_age and :end_age and rownum=1'; --两个命名参数 ,注意拼接的方法 --用 execute immediate 动态执行 SQL 语句
--注意其后的 into 字段值到变量的写法,还有 using 来代入参数
execute immediate v_sql_str into v_user_name,v_user_age using 18,25; dbms_output.put_line('第一个符合条件的用户:'||v_user_name||',年龄:'||v_user_age);
end;

3. 返回结果集

     CREATE OR REPLACE package pkg_test as
/* 定义ref cursor类型
不加return类型,为弱类型,允许动态sql查询,
否则为强类型,无法使用动态sql查询;
*/
type myrctype is ref cursor; --函数申明
function get(intID number) return myrctype;
end pkg_test;
/ CREATE OR REPLACE package body pkg_test as
--函数体
function get(intID number) return myrctype is
rc myrctype; --定义ref cursor变量
sqlstr varchar2(500);
begin
if intID=0 then
--静态测试,直接用select语句直接返回结果
open rc for select id,name,sex,address,postcode,birthday from
student;
else
--动态sql赋值,用:w_id来申明该变量从外部获得
sqlstr := 'select id,name,sex,address,postcode,birthday from student
where id=:w_id';
--动态测试,用sqlstr字符串返回结果,用using关键词传递参数
open rc for sqlstr using intid;
end if; return rc;
end get; end pkg_test;
/

四、存储过程一个总结的非常全的博客

http://www.cnblogs.com/chinafine/archive/2010/07/12/1776102.html

oracle 存储过程 动态sql语句的更多相关文章

  1. MySQL存储过程动态SQL语句的生成

    用Mysql存储过程来完成动态SQL语句,使用存储过程有很好的执行效率: 现在有要求如下:根据输入的年份.国家.节假日类型查询一个节假日,我们可以使用一般的SQL语句嵌入到Java代码中,但是执行效率 ...

  2. Oracle基础 动态SQL语句

    一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL ...

  3. mysql创建存储过程动态SQL语句

    DROP PROCEDURE IF EXISTS x.`wk`; DELIMITER $$ CREATE PROCEDURE `x`.`wk`() BEGIN ); ); SET t = CONCAT ...

  4. oracle存储过程,sql语句执行时间

    create or replace procedure sum_info is i integer; temp1 varchar2(50); temp2 varchar2(50); t1 date; ...

  5. 使用Oracle的DBMS_SQL包执行动态SQL语句

    引用自:http://blog.csdn.net/ggjjzhzz/archive/2005/10/17/507880.aspx 在某些场合下,存储过程或触发器里的SQL语句需要动态生成.Oracle ...

  6. 存储过程中执行动态Sql语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  7. 怎样SQL存储过程中执行动态SQL语句

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql;通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  8. mysql 存储过程中使用动态sql语句

    Mysql 5.0 以后,支持了动态sql语句,我们可以通过传递不同的参数得到我们想要的值 这里介绍两种在存储过程中的动态sql: set sql = (预处理的sql语句,可以是用concat拼接的 ...

  9. Oracle本地动态 SQL

    本地动态 SQL 首先我们应该了解什么是动态 SQL,在 Oracle数据库开发 PL/SQL块中我们使用的 SQL 分为:静态 SQL语句和动态 SQL语句.所谓静态 SQL指在 PL/SQL块中使 ...

随机推荐

  1. php 魔术方法__get()和__set()理解

    __get()方法,官方手册上是这样解释的 : ' 当调用(自己加的:或设置|赋值)当前环境下未定义或不可见的类属性或方法时,重载方法会被调用.本节后面将使用"不可访问属性(inaccess ...

  2. /dev/null 2>&1 解释(转)

    cmd >a 2>a 和 cmd >a 2>&1 为什么不同? cmd >a 2>a :stdout和stderr都直接送往文件 a ,a文件会被打开两遍, ...

  3. poj 3250 Bad Hair Day 单调栈入门

    Bad Hair Day 题意:给n(n <= 800,000)头牛,每头牛都有一个高度h,每头牛都只能看到右边比它矮的牛的头发,将每头牛看到的牛的头发加起来为多少? 思路:每头要进栈的牛,将栈 ...

  4. <二> SQL 基础

    left (outer) join 结果集包含连接表的匹配行,也包括左连接表的所有行. select a.a, a.b, a.c, b.c b.d b.f from a left out join b ...

  5. 时钟周期、振荡周期、机器周期、CPU周期、状态周期、指令周期、总线周期、任务周期

    http://blog.csdn.net/yangtalent1206/article/details/5853017 计算机系统有一系列的“周期”概念,区别.联系地理解这些概念至关重要.以下对时钟周 ...

  6. hadoop2.4.0 安装配置 (2)

    hdfs-site.xml 配置如下: <?xml version="1.0" encoding="UTF-8"?> <?xml-styles ...

  7. bzoj 4127: Abs 树链剖分

    4127: Abs Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 11  Solved: 5[Submit][Status][Discuss] Des ...

  8. location.hash && location.href

    hash:设置或获取 href 属性中在井号“#”后面的分段. href:设置或获取整个URL为字符串. 通过下面的测试你会发现区别,将代码放到你的HTML中,然后用浏览器打开,测试步骤: 点击“超链 ...

  9. location.search 详解

    JS中location.search什么意思 设置或获取网页地址跟在问号后面的部分 当以get方式在url中传递了请求参数时,可以利用location的search属性提取参数的值,下面的代码把参数的 ...

  10. sql replace into 与 insert into

    sql replace into用法详细说明 REPLACE的运行与INSERT很相似.只有一点例外,假如表中的一个旧记录与一个用于PRIMARY KEY或一个UNIQUE索引的新记录具有相同的值,则 ...