Oracle过程中执行动态SQL或DDL语句
oracle中executeimmediate的使用

oracle中executeimmediate的使用EXECUTE IMMEDIATE 是 Oracle 数据库的一个动态 SQL 语句执行命令。
它允许在运行时动态地构建和执行 SQL 语句的字符串,而不需要预编译。
EXECUTEIMMEDIATE执行的SQL语句可以是任何有效的SQL语句,包括SELECT、INSERT、UPDATE、DELETE等语句。
它可以使用变量和参数进行动态的值替换。
使用EXECUTEIMMEDIATE可以在运行时根据不同的条件和需求构建不同的SQL语句,从而实现更大的灵活性和可重用性。
以下是EXECUTEIMMEDIATE的一些常见用法:1.动态执行SELECT语句可以使用EXECUTEIMMEDIATE动态执行SELECT语句,并将结果存储在变量中。
例如:DECLAREl_emp_id NUMBER := 100;l_emp_name VARCHAR2(100);BEGINEXECUTE IMMEDIATE 'SELECT emp_name INTO :1 FROM employees WHERE emp_id = :2' INTO l_emp_name USING OUT l_emp_name,l_emp_id;DBMS_OUTPUT.PUT_LINE('Employee Name: ' , l_emp_name);END;在上面的示例中,通过使用 USING OUT 子句将变量 l_emp_name 传递给 EXECUTE IMMEDIATE,并在动态 SQL 语句中使用该变量。
使用 INTO 子句将结果存储在 l_emp_name 变量中。
2.动态执行DDL语句EXECUTEIMMEDIATE还可以用于动态执行DDL(数据定义语言)语句,例如创建表、修改表结构等。
例如:DECLAREl_table_name VARCHAR2(100);BEGINl_table_name := 'employees';EXECUTE IMMEDIATE 'DROP TABLE ' , l_table_name;DBMS_OUTPUT.PUT_LINE('Table ' , l_table_name , ' dropped successfully.');END;上面的示例使用 EXECUTE IMMEDIATE 删除名为 employees 的表。
oracle存储过程动态sql语句

oracle存储过程动态sql语句⼀、在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就会报错。
解决⽅法:⽅法⼀:就写个存储过程,然后⽤参数传过去就没问题了。
declarev_clob clob :='⼀个长⽂章';begininsert 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) isstr varchar(1000);--注意tab1必须要更改,发现原来的logmnr_contents20140524中的sql_redo为varchar,需要改成clobbeginstr:= 'insert into '||tab1||' values(:1,:2,:3,:4,:5,:6,:7,:8,:9)';execute immediate str using scns,to_date(timestamps,'yyyy-MM-ddhh24: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)IStext_Var CLOB;amount_Var NUMBER;offset_Var NUMBER;BEGININSERT INTO test VALUES(pId,empty_clob());SELECT text INTO text_var FROM testWHERE id=pId;amount_var:=LENGTH(outVar);offset_var:=1;DBMS_LOB.WRITE(text_Var,amount_Var,offset_Var,outVar);COMMIT;END p_In_Clob;调⽤存储过程:beginp_In_Clob(1,'...');end;三、oracle 存储过程使⽤动态sqlOracle存储过程使⽤动态SQL 有两种写法:⽤ DBMS_SQL 或 execute immediate,建议使⽤后者。
oracle中execute_immediate的使用

oracle中execute_immediate的使用在Oracle数据库中,EXECUTE_IMMEDIATE是一条SQL语句,用于在执行过程中动态执行SQL语句。
EXECUTE_IMMEDIATE允许在一个PL/SQL块中动态执行任何有效的SQL或PL/SQL语句。
它允许通过字符串形式指定SQL语句,从而实现动态生成和执行SQL语句的目的。
EXECUTE_IMMEDIATE语句的基本语法如下:EXECUTE_IMMEDIATE (sql_statement [INTO { define_variable[, define_variable]..., record_variable}] [USING [in , out , in out] bind_argument[, [in , out , in out] bind_argument]...]);其中,sql_statement是要执行的SQL语句的字符串形式。
可以使用任何合法的SQL语句,如SELECT,INSERT,UPDATE,DELETE或PL/SQL块。
如果想要从查询中检索数据,则可以使用INTO子句将结果存储在变量中。
除了SQL语句本身之外,还可以使用USING子句传递绑定参数。
绑定参数可以在运行时动态地传递给SQL语句,从而增加灵活性和安全性。
绑定参数可以使用IN,OUT和INOUT模式指定,以指示参数是输入、输出还是输入输出参数。
以下是EXECUTE_IMMEDIATE语句的一些常见用法:1.动态创建表格:DECLAREv_table_name VARCHAR2(30) := 'my_table';BEGINEXECUTE IMMEDIATE 'CREATE TABLE ',v_table_name,' (id NUMBER, name VARCHAR2(30))';END;在上述示例中,通过传递v_table_name变量的值,可以动态创建一个表格。
ORACLE动态执行SQL语句

3. 返回结果集
str_column:='sal';--查询的列 str_Total:=0;--总和
str_sql:=' select '|| 'str_column' ||' from emp ' ; execute immediate str_sql into str_Total;
2. 返回单条结果
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_||R_1.ADDRESS); end ;
网络错误503请刷新页面重试持续报错请尝试更换浏览器或网络环境
ORACLE动态执行 SQL语句
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。试验步骤如下:
Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用egin 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_2:='北京'; str := 'INSERT INTO test (name ,address) VALUES (:1, :2)'; EXECUTE IMMEDIATE str USING v_1, v_2; commit; end;
在Oracle中执行动态SQL的几种方法

在Oracle中执⾏动态SQL的⼏种⽅法转载:以下为内容留存:在中执⾏动态SQL的⼏种⽅法在⼀般的sql操作中,sql语句基本上都是固定的,如:SELECT t.empno,t.ename FROM scott.emp t WHERE t.deptno = 20;但有的时候,从应⽤的需要或程序的编写出发,都可能需要⽤到动态SQl,如:当 from 后的表不确定时,或者where 后的条件不确定时,都需要⽤到动态SQL。
⼀、使⽤动态游标实现1、声明动态游标TYPE i_cursor_type IS REF CURSOR;2、声明游标变量my_cursor i_cursor_type;3、使⽤游标n_deptno:=20;dyn_select := 'select empno,ename from emp where deptno='||n_deptno;OPEN my_cursor FOR dyn_select;LOOPFETCH my_cursor INTO n_empno,v_ename;EXIT WHEN my_cursor%NOTFOUND;--⽤n_empno,v_ename做其它处理--....END LOOP;CLOSE dl_cursor;4、⼩结:动态游标可以胜任⼤多数动态SQL的需求了,使⽤简洁⽅便居家旅⾏之必备杀⼈放⽕之法宝。
⼆、使⽤ EXECUTE IMMEDIATE最早⼤家都使⽤DBMS_SQL包,但是太太⿇烦了,最终都放弃了。
但是⾃从有了EXECUTE IMMEDIATE之后,但要注意以下⼏点:EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执⾏动态的SQL语句或⾮运⾏时创建的PL/SQL块.动态创建和执⾏SQL语句性能超前,EXECUTE IMMEDIATE的⽬标在于减⼩企业费⽤并获得较⾼的性能,较之以前它相当容易编码.尽管DBMS_SQL仍然可⽤,但是推荐使⽤EXECUTE IMMEDIATE,因为它获的收益在包之上。
oracle execute immediate用法

oracle execute immediate用法在Oracle数据库中,EXECUTE IMMEDIATE语句用于动态执行SQL 或PL/SQL代码。
以下是EXECUTE IMMEDIATE的一些常见用法:执行动态SQL查询:
sql复制代码
EXECUTE IMMEDIATE 'SELECT column1, column2 FROM table WHERE condition';
执行动态INSERT操作:
sql
EXECUTE IMMEDIATE 'INSERT INTO table (column1, column2) VALUES (:value1, :value2)';
执行动态UPDATE操作:
sql
EXECUTE IMMEDIATE 'UPDATE table SET column1 = :value WHERE condition';
执行动态DELETE操作:
sql
EXECUTE IMMEDIATE 'DELETE FROM table WHERE condition';
在上述示例中,你可以使用绑定变量(例如::value1、:value2等)来绑定实际的参数值,这样可以避免SQL注入攻击,并提高代码的可读性和可维护性。
除了基本的EXECUTE IMMEDIATE语句外,你还可以使用其他功能和选项来扩展其功能,例如使用绑定变量、错误处理、动态创建表等。
你可以查阅Oracle文档以获取更多关于EXECUTE IMMEDIATE的详细信息和示例。
oracle数据库ddl语句

oracle数据库ddl语句Oracle数据库DDL语句是用于定义、修改和删除数据库对象的语句。
DDL 是数据定义语言(Data Definition Language)的缩写,它包括了一系列的命令,如CREATE、ALTER和DROP等,用于管理数据库的结构和元数据。
在本文中,我们将逐步回答关于Oracle数据库DDL语句的一系列问题。
什么是Oracle数据库DDL语句?Oracle数据库DDL语句指的是用于管理数据库结构和元数据的命令。
这些命令允许我们创建、修改和删除数据库对象,如表、视图、索引、序列和约束等。
DDL语句允许数据库管理员对数据库进行结构上的修改,以适应业务需求的变化。
有哪些常用的Oracle数据库DDL语句?Oracle数据库提供了一套完整的DDL语句,以下是一些常用的DDL语句:1. CREATE TABLE语句:用于创建一个新的数据库表。
可以定义表的列以及各个列的数据类型和约束。
2. ALTER TABLE语句:用于修改已存在的数据库表的结构。
可以添加或删除列,修改列的数据类型,以及添加或删除约束等。
3. DROP TABLE语句:用于删除一个数据库表及其数据。
这将会删除表的结构以及与该表关联的索引、触发器等。
4. CREATE INDEX语句:用于创建一个新的索引。
索引可以加速对数据库表的查询操作。
5. ALTER INDEX语句:用于修改已存在的索引的结构。
可以修改索引的名称、添加或删除索引的列等。
6. DROP INDEX语句:用于删除一个索引。
7. CREATE VIEW语句:用于创建一个新的视图。
视图是一个虚拟表,它包含基础表中的数据,但不实际存储数据。
8. ALTER VIEW语句:用于修改已存在的视图的结构。
9. DROP VIEW语句:用于删除一个视图。
10. CREATE SEQUENCE语句:用于创建一个新的序列。
序列是一种自动递增的数字。
11. ALTER SEQUENCE语句:用于修改已存在的序列的属性。
动态SQL的使用方法

动态SQL的使⽤⽅法⼀般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使⽤SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使⽤,要想实现在PL/SQL中使⽤DDL语句及系统控制语句,可以通过使⽤动态SQL来实现。
⾸先我们应该了解什么是动态SQL,在Oracle数据库开发PL/SQL块中我们使⽤的SQL分为:静态SQL语句和动态SQL语句。
所谓静态SQL指在PL/SQL块中使⽤的SQL语句在编译时是明确的,执⾏的是确定对象。
⽽动态SQL是指在PL Oracle中动态SQL可以通过本地动态SQL来执⾏,也可以通过DBMS_SQL包来执⾏。
下⾯就这两种情况分别进⾏说明: ⼀、本地动态SQL 本地动态SQL是使⽤EXECUTE IMMEDIATE语句来实现的。
1、本地动态SQL执⾏DDL语句: 需求:根据⽤户输⼊的表名及字段名等参数动态建表。
create or replace procedure proc_test(table_name in varchar2, --表名field1 in varchar2, --字段名datatype1 in varchar2, --字段类型field2 in varchar2, --字段名datatype2 in varchar2--字段类型) asstr_sql varchar2(500);beginstr_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;execute immediate str_sql; --动态执⾏DDL语句exceptionwhen others thennull;end ; 以上是编译通过的存储过程代码。
下⾯执⾏存储过程动态建表。
SQL>execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);PL/SQL procedure successfully completedSQL>desc dinya_test;Name Type Nullable Default Comments---- ------------- -------- ------- --------ID NUMBER(8)NAME VARCHAR2(100) YSQL> 到这⾥,就实现了我们的需求,使⽤本地动态SQL根据⽤户输⼊的表名及字段名、字段类型等参数来实现动态执⾏DDL语句。
oracle存储过程executeimmediate用法

oracle存储过程executeimmediate用法Oracle数据库中的EXECUTE IMMEDIATE语句用于在存储过程或匿名块中执行动态SQL语句。
它允许在运行时构建和执行SQL语句,而不是在编译时确定。
EXECUTEIMMEDIATE语句的基本语法如下:EXECUTE IMMEDIATE <sql_statement>;其中,<sql_statement>是要执行的动态SQL语句。
可以是一个字符串常量,也可以是一个字符串变量。
使用EXECUTEIMMEDIATE的主要优点是它提供了更大的灵活性和动态性。
它可以用于执行任意的SQL语句,包括SELECT、INSERT、UPDATE和DELETE语句,以及DDL语句如CREATETABLE、ALTERTABLE和DROPTABLE 等。
这使得存储过程和匿名块能够根据不同的条件和参数执行不同的SQL 语句。
以下是一些EXECUTEIMMEDIATE语句的示例用法:1.执行SELECT语句并将结果存储在游标中:DECLAREmy_cursor SYS_REFCURSOR;BEGINEXECUTE IMMEDIATE 'SELECT * FROM my_table' INTO my_cursor;--处理游标中的结果END;2.执行INSERT语句插入数据:DECLAREv_value NUMBER := 100;BEGINEXECUTE IMMEDIATE 'INSERT INTO my_table (column1) VALUES (:value)' USING v_value;--插入数据END;3.执行UPDATE语句更新数据:DECLAREv_id NUMBER := 1;v_value NUMBER := 100;BEGINEXECUTE IMMEDIATE 'UPDATE my_table SET column1 = :value WHERE id = :id' USING v_value, v_id;--更新数据END;4.执行DELETE语句删除数据:DECLAREv_id NUMBER := 1;BEGINEXECUTE IMMEDIATE 'DELETE FROM my_table WHERE id = :id' USING v_id;--删除数据END;5.执行DDL语句创建表:DECLAREv_table_name VARCHAR2(100) := 'my_table';BEGINEXECUTE IMMEDIATE 'CREATE TABLE ' , v_table_name , ' (id NUMBER, name VARCHAR2(100))';--创建表END;需要注意的是,EXECUTEIMMEDIATE语句在执行动态SQL语句时,需要对输入的参数进行绑定。
Oracle动态SQL语句的简单执行

Oracle动态SQL语句的简单执⾏在使⽤进⾏Oracle编程时,有时候SQL语句⾮常复杂,需要采⽤动态构造查询语句的情况,有两种⽅法可以构造动态的SQL语句,并执⾏返回结果集。
1、在数据访问层构造SQL语句例如下⾯的语句,将构造完整的SQL语句赋值给CommandText,再传递到数据库进⾏执⾏,返回结果集。
mandType = CommandType.TextmandText = "Select * From Users"dataAdapter .SelectCommand = loadCommanddataAdapter . Fill(data)dataAdapter .SelectCommand = loadCommanddataAdapter . Fill(data)该⽅法需要将整个SQL的构造过程放在DataAccess层,业务逻辑发⽣变化,修改不⽅便,⽽且每次查询需要传递给数据库很长的查询字符串,传递参数的效率也不⾼。
2、在存储过程中构造动态SQL语句并执⾏以下为⼀个完整的事例(经过删减),其中RefCursor 为⾃定义游标类型PROCEDURE G_Search(P_YearNO IN NUMBER,P_ControlType IN NUMBER,P_Progress IN CHAR,P_DepartID IN VARCHAR2,P_ProjectName IN NVARCHAR2,C_Projects OUT RefCursor) ISe_ErrInterruption EXCEPTION;v_ErrID NUMBER; --Variable to hold the errorlog idv_ErrCode NUMBER; --Variable to hold the error message codev_ErrText VARCHAR2(512); --Variable to hold the error message textv_ErrProc VARCHAR2(50) :='G_Search';v_DepartID VARCHAR2(16);v_ProjectName NVARCHAR2(128);v_SQL VARCHAR2(512);v_Where VARCHAR2(256);BEGINv_SQL :='SELECT PROJECTID, PARENTID, PROJECTNAME ';v_SQL := v_SQL ||' FROM PROJECTS A';v_Where :=' Where';-- 年度IF P_YearNO <9999THENv_Where := v_Where ||' A.YearNO = '|| P_YearNO ||' And';ELSEv_Where := v_Where ||' A.YearNO < '|| P_YearNO ||' And';END IF;-- 控制类别IF P_ControlType =9THENv_Where := v_Where ||' A.ControlType < 9 And';ELSEv_Where := v_Where ||' A.ControlType = '|| P_ControlType ||' And';END IF;-- 进度IF P_Progress <'Z'THENv_Where := v_Where ||' A.Progress = '''|| P_Progress ||''' And';ELSEv_Where := v_Where ||' A.Progress < '''|| P_Progress ||''' And';END IF;IF TRIM(P_DepartID) <>'%'THENv_Where := v_Where ||' A.DepartID = '''|| P_DepartID ||''' And';ELSEv_Where := v_Where ||' A.DepartID Like '''|| P_DepartID ||''' And';END IF;--项⽬名称v_ProjectName := NVL(P_ProjectName,'%');IF v_ProjectName <>'%'THENv_ProjectName :='%'|| P_ProjectName ||'%';END IF;v_Where := v_Where ||' A.ProjectName Like '||''''|| v_ProjectName ||''' And';v_SQL := v_SQL || v_Where;OPEN C_PROJECTS FOR v_SQL;--COMMIT;EXCEPTION--根据需要定义错误异常WHEN OTHERS THEN--ROLLBACK;v_ErrID := SQLCODE;v_ErrText := SQLERRM;raise_application_error(v_ErrID,v_ErrText);END G_Search;该⽅法只需要传递给存储过程⼀些参数,使⽤游标返回数据。
oracle动态sql语句基本语法

oracle动态sql语句基本语法Oracle动态SQL语句是一种在运行时动态生成SQL语句的技术。
它可以根据不同的条件和参数生成不同的SQL语句,从而实现更加灵活和高效的数据操作。
下面是Oracle动态SQL语句的基本语法:1. 使用EXECUTE IMMEDIATE语句执行动态SQL语句:EXECUTE IMMEDIATE 'SELECT * FROM employees WHERE department_id = :dept_id' USING dept_id;2. 使用BIND VARIABLES绑定变量:DECLAREv_dept_id NUMBER := 10;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id = :dept_id';EXECUTE IMMEDIATE v_sql USING v_dept_id;END;3. 使用PL/SQL变量拼接SQL语句:DECLAREv_dept_id NUMBER := 10;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id = ' || v_dept_id;EXECUTE IMMEDIATE v_sql;END;4. 使用CASE语句生成动态SQL语句:DECLAREv_dept_id NUMBER := 10;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id = ';v_sql := v_sql || CASE WHEN v_dept_id IS NULL THEN 'NULL' ELSE TO_CHAR(v_dept_id) END;EXECUTE IMMEDIATE v_sql;END;5. 使用FOR LOOP生成动态SQL语句:DECLAREv_dept_id NUMBER := 10;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id IN (';FOR i IN 1..10 LOOPv_sql := v_sql || i || ',';END LOOP;v_sql := SUBSTR(v_sql, 1, LENGTH(v_sql) - 1) || ')';EXECUTE IMMEDIATE v_sql;END;6. 使用SYS_CONTEXT函数获取当前用户信息:DECLAREv_user VARCHAR2(30) := SYS_CONTEXT('USERENV', 'CURRENT_USER');v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE created_by = ''' || v_user || '''';EXECUTE IMMEDIATE v_sql;END;7. 使用DBMS_SQL包执行动态SQL语句:DECLAREv_cursor INTEGER;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id = :dept_id';v_cursor := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);DBMS_SQL.BIND_VARIABLE(v_cursor, ':dept_id', 10);DBMS_SQL.EXECUTE(v_cursor);DBMS_SQL.CLOSE_CURSOR(v_cursor);END;8. 使用DBMS_SQL.RETURN_RESULT函数返回结果集:DECLAREv_cursor INTEGER;v_sql VARCHAR2(100);BEGINv_sql := 'SELECT * FROM employees WHERE department_id = :dept_id';v_cursor := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);DBMS_SQL.BIND_VARIABLE(v_cursor, ':dept_id', 10);DBMS_SQL.EXECUTE(v_cursor);DBMS_SQL.RETURN_RESULT(v_cursor);DBMS_SQL.CLOSE_CURSOR(v_cursor);END;9. 使用DBMS_SQL.DESCRIBE_COLUMNS函数获取结果集元数据:DECLAREv_cursor INTEGER;v_sql VARCHAR2(100);v_col_cnt INTEGER;v_col_desc DBMS_SQL.DESC_TAB;BEGINv_sql := 'SELECT * FROM employees WHERE department_id = :dept_id';v_cursor := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);DBMS_SQL.BIND_VARIABLE(v_cursor, ':dept_id', 10);DBMS_SQL.EXECUTE(v_cursor);v_col_cnt := DBMS_SQL.FETCH_ROWS(v_cursor);DBMS_SQL.DESCRIBE_COLUMNS(v_cursor, v_col_cnt, v_col_desc); DBMS_SQL.CLOSE_CURSOR(v_cursor);END;10. 使用DBMS_SQL.COLUMN_VALUE函数获取结果集列值:DECLAREv_cursor INTEGER;v_sql VARCHAR2(100);v_col_cnt INTEGER;v_col_desc DBMS_SQL.DESC_TAB;v_emp_id NUMBER;v_emp_name VARCHAR2(30);BEGINv_sql := 'SELECT employee_id, first_name FROM employees WHERE department_id = :dept_id';v_cursor := DBMS_SQL.OPEN_CURSOR;DBMS_SQL.PARSE(v_cursor, v_sql, DBMS_SQL.NATIVE);DBMS_SQL.BIND_VARIABLE(v_cursor, ':dept_id', 10);DBMS_SQL.EXECUTE(v_cursor);v_col_cnt := DBMS_SQL.FETCH_ROWS(v_cursor);DBMS_SQL.DESCRIBE_COLUMNS(v_cursor, v_col_cnt, v_col_desc); LOOPEXIT WHEN DBMS_SQL.FETCH_ROWS(v_cursor) = 0;DBMS_SQL.COLUMN_VALUE(v_cursor, 1, v_emp_id);DBMS_SQL.COLUMN_VALUE(v_cursor, 2, v_emp_name);DBMS_OUTPUT.PUT_LINE(v_emp_id || ' ' || v_emp_name);END LOOP;DBMS_SQL.CLOSE_CURSOR(v_cursor);END;以上是Oracle动态SQL语句的基本语法,可以根据实际需求进行灵活应用。
ORACLE动态执行SQL语句

ORACLE动态执行SQL语句
在ORACLE中,可以使用EXECUTEIMMEDIATE语句来动态执行SQL语句。
这个语句可以接受一个字符串作为参数,然后将该字符串作为SQL语句进
行执行。
下面是一个示例:
```
DECLARE
sql_stmt VARCHAR2(100);
BEGIN
sql_stmt := 'INSERT INTO employees (employee_id, first_name, last_name) VALUES (1, ''John'', ''Doe'')';
EXECUTE IMMEDIATE sql_stmt;
sql_stmt := 'SELECT * FROM employees WHERE employee_id = 1';
EXECUTE IMMEDIATE sql_stmt;
END;
```
在上面的示例中,我们首先构造了一个INSERT语句,然后通过EXECUTE IMMEDIATE语句执行该语句,将一个员工数据插入到employees
表中。
然后,我们又构造了一个SELECT语句,并通过EXECUTE IMMEDIATE语句执行该语句,返回了符合条件的员工数据。
需要注意的是,在构造SQL语句时需要注意使用逃逸字符来处理字符串中的引号。
另外,动态执行SQL语句存在一定的安全风险,应该谨慎使用,并对用户输入进行适当的验证和过滤。
oracle存储过程调用动态sql

oracle存储过程调⽤动态sqloracle 存储过程调⽤动态sqlCreationTime--2018年8⽉16⽇11点25分Author:Marydon1.错误实现⽅式--开始时间拼接' 00:00:00'V_SQL := 'select decode(length(' || V_END || '),10,' || 'concat(' || V_END || ', 00:00:00),' || V_END || ') from dual';EXECUTE IMMEDIATE V_SQL; 编译成功,但是存储过程调⽤失败。
2.原因分析 在oracl数据库中,ddl表⽰数据库定义语⾔,即我们平常使⽤的sql语句,声明的sql语句可以直接使⽤拼接字符串进⾏拼接; dml表⽰数据操纵语⾔,声明的sql语句不能再⽤管道符||来动态拼接变量。
3.正确实现⽅式 execute immediate属于dml,dml使⽤sql的规则如下: 声明sql语句 字符串拼接变量时,变量要使⽤占位符来代替,格式为 ":" + "名字",名字随意 调⽤sql语句 使⽤"using"来传递变量,代替占位符,格式为 "using var1,var2,..."V_SQL := 'select decode(length(:v1),10,:v2,:v3) from dual';EXECUTE IMMEDIATE V_SQL INTO V_START USING V_START,V_START || ' 00:00:00',V_START; 结果展⽰:4.测试 ⼊参 出参5.最简单的⽅式 结果如下 另外对于单引号的转义,两个紧挨的单引号相关推荐:。
关于Oracle 的定时执行作业问题(动态PLSQL)

方法:oracle 的动态SQL,一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使用动态SQL来实现。
如何把下数的业务用PL/SQL实现?1.业务操作流水表ODS_PRODUCT_SEQUENCE_DM_434操作日期:每月1日上午即可操作方式:按标号顺序在一个ORACLE SQL*PLUS中顺序执行(1)备份conn boss/******8@jyfx36;select count(*) from jlcrm.ods_product_sequence_dm_434where start_datetime>=to_date('20090201','yyyymmdd')and start_datetime<to_date('20090301','yyyymmdd');conn boss/******@sp87;select count(*) from yxf_oper_200902where start_datetime>=to_date('20090201','yyyymmdd')and start_datetime<to_date('20090301','yyyymmdd');如上述两个执行结果相等,备份成功,否则,重新查找原因。
解决办法:CREATE OR REPLACE PROCEDURE "SCOTT"."BACKDATA" (vdate in varchar2) asstr_sql1 varchar2(500);str_sql2 varchar2(150);str_sql3 varchar(350);str_sql4 varchar2(450);str_sql5 varchar(450);cnt int;tablename varchar(20):='yxf_oper_'||vdate;beginselect count(*) into cnt from cat where table_name=upper(trim(tablename));if cnt > 0 thenstr_sql2:='drop table ' ||tablename ;execute immediate str_sql2 ;end if;str_sql1:= 'create table ' || tablename || ' as select * from yxf_oper_mode' ;execute immediate str_sql1 ;str_sql3:= 'insert into yxf_oper_'|| vdate || '(select * from yxf_oper_'|| vdate || 'tmp where start_datetime>=to_date('||''''|| vdate || '01' ||''''||',' || '''yyyymmdd''' || ')'||' andstart_datetime<=to_date('||''''||vdate ||'31'||'''' ||',' || '''yyyymmdd'''||'))' ;-- execute immediate str_sql3 ;--execute immediate 'commit';str_sql4:='create index inde_yxf_oper_' || vdate|| ' on yxf_oper_' || vdate || ' (phone_no)' ;-- execute immediate str_sql4 ;str_sql5:='create index inde_yxf_oper_1'||vdate||' on yxf_oper_'||vdate||' (id_no)';-- execute immediate str_sql5 ;DBMS_OUTPUT.PUT_LINE(str_sql1);-- DBMS_OUTPUT.PUT_LINE(str_sql2);DBMS_OUTPUT.PUT_LINE(str_sql3);DBMS_OUTPUT.PUT_LINE(str_sql4);DBMS_OUTPUT.PUT_LINE(str_sql5);exceptionwhen others thenDBMS_OUTPUT.PUT_LINE('error');end ;。
使用Oracle的DBMS_SQL包执行动态SQL语句

ÔÚijЩ³¡ºÏÏ£¬´æ´¢¹ý³Ì»ò´¥·¢Æ÷ÀïµÄSQLÓï¾äÐèÒª¶¯Ì¬Éú³É¡£OracleµÄDBMS_SQL°ü¿ÉÒÔÓÃÀ´Ö´Ðж¯Ì¬SQLÓï¾ä¡£±¾ÎÄͨ¹ýÒ»¸ö¼òµ¥µÄÀý×ÓÀ´Õ¹Ê¾ÈçºÎÀûÓÃDBMS_SQL°üÖ´Ðж¯Ì¬SQLÓï¾ä£ºDECLAREv_cursor NUMBER;v_stat NUMBER;v_row NUMBER;v_id NUMBER;v_no VARCHAR(100);v_date DATE;v_sql VARCHAR(200);s_id NUMBER;s_date DATE;BEGINs_id := 3000;s_date := SYSDATE;v_sql := 'SELECT id,qan_no,sample_date FROM "tblno" WHERE id > :sid and sample_date < :sdate';v_cursor := dbms_sql.open_cursor; --´ò¿ªÓαꣻdbms_sql.parse(v_cursor, v_sql, dbms_sql.native); --½âÎö¶¯Ì¬SQLÓï¾ä£»dbms_sql.bind_variable(v_cursor, ':sid', s_id); --°ó¶¨ÊäÈë²ÎÊý£»dbms_sql.bind_variable(v_cursor, ':sdate', s_date);dbms_sql.define_column(v_cursor, 1, v_id); --¶¨ÒåÁÐdbms_sql.define_column(v_cursor, 2, v_no, 100);dbms_sql.define_column(v_cursor, 3, v_date);v_stat := dbms_sql.execute(v_cursor); --Ö´Ðж¯Ì¬SQLÓï¾ä¡£LOOPEXIT WHEN dbms_sql.fetch_rows(v_cursor)<=0; --fetch_rowsÔÚ½á¹û¼¯ÖÐÒƶ¯Óα꣬Èç¹ûδµÖ´ïĩ⣬·µ»Ø1¡£dbms_sql.column_value(v_cursor, 1, v_id); --½«µ±Ç°ÐеIJéѯ½á¹ûдÈëÉÏÃ涨ÒåµÄÁÐÖС£dbms_sql.column_value(v_cursor, 2, v_no);dbms_sql.column_value(v_cursor, 3, v_date);dbms_output.put_line(v_id || ';' || v_no || ';' || v_date);END LOOP;dbms_sql.close_cursor(v_cursor); --¹Ø±ÕÓαꡣEND;½á¹û£º3095;S051013XW00010;15-10ÔÂ-053112;A051013XW00027;10-10ÔÂ-053113;A051013XW00028;13-10ÔÂ-053116;S051013XW00031;13-10ÔÂ-05¸½£ºDBMS_SQLµÄÎĵµ(À´Ô´£º)Oracle DBMS_SQLVersion 10.2GeneralNote: DMBS_SQL is the traditional form of dynamic SQL in Oracle.For most purposes native dynamic sql (NDS) will suffice but there are some things the DBMS_SQL package does that can not be done any other way. This page emphasizes those areas where there is no substitute.PurposeSource {ORACLE_HOME}/rdbms/admin/dbmssql.sqlConstants Name Data Type Valuev6 INTEGER 0native INTEGER 1v7 INTEGER 2Defined Data Types General TypesTYPE desc_rec IS RECORD (col_type binary_integer := 0,col_max_len binary_integer := 0,col_name varchar2(32) := '',col_name_len binary_integer := 0,col_schema_name varchar2(32) := '',col_schema_name_len binary_integer := 0,col_precision binary_integer := 0,col_scale binary_integer := 0,col_charsetid binary_integer := 0,col_charsetform binary_integer := 0,col_null_ok boolean := TRUE);TYPE desc_rec2 IS RECORD (col_type binary_integer := 0,col_max_len binary_integer := 0,col_name varchar2(32767) := '',col_name_len binary_integer := 0,col_schema_name varchar2(32) := '',col_schema_name_len binary_integer := 0,col_precision binary_integer := 0,col_scale binary_integer := 0,col_charsetid binary_integer := 0,col_charsetform binary_integer := 0,col_null_ok boolean := TRUE);TYPE desc_tab IS TABLE OF desc_recINDEX BY binary_integer;TYPE desc_tab2 IS TABLE OF desc_rec2INDEX BY binary_integer;TYPE varchar2a IS TABLE OF VARCHAR2(32767)INDEX BY binary_integer;TYPE varchar2s IS TABLE OF VARCHAR2(256)INDEX BY binary_integer;Bulk SQL TypesTYPE Bfile_Table IS TABLE OF bfileINDEX BY binary_integer;TYPE Binary_Double_Table IS TABLE OF binary_double INDEX BY binary_integer;TYPE Binary_Float_Table IS TABLE OF binary_float INDEX BY binary_integer;TYPE Blob_Table IS TABLE OF blobINDEX BY binary_integer;TYPE Clob_Table IS TABLE OF clobINDEX BY binary_integer;TYPE Date_Table IS TABLE OF dateINDEX BY binary_integer;TYPE interval_day_to_second_Table IS TABLE OFdsinterval_unconstrained INDEX BY binary_integer;TYPE interval_year_to_MONTH_Table IS TABLE OFyminterval_unconstrainedINDEX BY binary_integer;TYPE Number_Table IS TABLE OF NUMBERINDEX BY binary_integer;TYPE time_Table IS TABLE OF time_unconstrainedINDEX BY binary_integer;TYPE time_with_time_zone_Table IS TABLE OF TIME_TZ_UNCONSTRAINED INDEX BY binary_integer;TYPE timestamp_Table IS TABLE OF timestamp_unconstrainedINDEX BY binary_integer;TYPE timestamp_with_ltz_table IS TABLE OFTIMESTAMP_LTZ_UNCONSTRAINEDINDEX BY binary_integer;TYPE Urowid_Table IS TABLE OF urowidINDEX BY binary_integer;TYPE timestamp_with_time_zone_table IS TABLE OFTIMESTAMP_TZ_UNCONSTRAINEDINDEX BY binary_integer;TYPE Varchar2_Table IS TABLE OF VARCHAR2(2000)INDEX BY binary_integer;Dependencies SELECT nameFROM dba_dependenciesWHERE referenced_name = 'DBMS_SQL'UNIONSELECT referenced_nameFROM dba_dependenciesWHERE name = 'DBMS_SQL';Exceptions Error Code ReasonORA-06562 Inconsistent types: Raised by procedure "column_value" or"variable_value" if the type of the given out argument where to put the requested value is different from the type of the valueBIND_ARRAYBinds a given value to a given collection dbms_sql.BIND_ARRAY(c IN INTEGER,name IN VARCHAR2,<table_variable> IN <datatype>[,index1 IN INTEGER,index2 IN INTEGER)]);DECLAREstmt VARCHAR2(200);dept_no_array dbms_sql.number_table;c NUMBER;dummy NUMBER;BEGINdept_no_array(1) := 10; dept_no_array(2) := 20;dept_no_array(3) := 30; dept_no_array(4) := 40;dept_no_array(5) := 30; dept_no_array(6) := 40;stmt := 'delete from emp where deptno = :dept_array';c := dbms_sql.open_cursor;dbms_sql.parse(c, stmt, dbms_sql.NATIVE);dbms_sql.bind_array(c, ':dept_array', dept_no_array, 1, 4);dummy := dbms_sql.execute(c);dbms_sql.close_cursor(c);EXCEPTIONSWHEN OTHERS THENIF dbms_sql.is_open(c) THENdbms_sql.close_cursor(c);END IF;RAISEEND;/BIND_VARIABLEBinds a given value to a given variable dbms_sql.bind_variable (c IN INTEGER,name IN VARCHAR2,value IN <datatype>)CREATE OR REPLACE PROCEDURE demo(salary IN NUMBER) AScursor_name INTEGER;rows_processed INTEGER;BEGINcursor_name := dbms_sql.open_cursor;dbms_sql.parse(cursor_name, 'DELETE FROM emp WHERE sal > :x',dbms_sql.NATIVE);dbms_sql.bind_variable(cursor_name, ':x', salary);rows_processed := dbms_sql.execute(cursor_name);dbms_sql.close_cursor(cursor_name);EXCEPTIONWHEN OTHERS THENdbms_sql.close_cursor(cursor_name);END;/BIND_VARIABLE_CHARBinds a given value to a given variable dbms_sql.bind_variabl_char (c IN INTEGER,name IN VARCHAR2,value IN CHAR CHARACTER SET ANY_CS [,out_value_size IN INTEGER]);See bind_variable demoBIND_VARIABLE_RAWBinds a given value to a given variable dbms_sql.bind_variable_raw (c IN INTEGER,name IN VARCHAR2,value IN RAW [,out_value_size IN INTEGER]);See bind_variable demoBIND_VARIABLE_ROWIDBinds a given value to a given variable dbms_sql.bind_variable_rowid ( c IN INTEGER,name IN VARCHAR2,value IN ROWID);See bind_variable demoCLOSE_CURSORCloses cursor and free memory dbms_sql.close_cursor(c IN OUT INTEGER); See is_open demoCOLUMN_VALUEReturns value of the cursor element for a given position in a cursor dbms_sql.column_value (c IN INTEGER,position IN INTEGER,value OUT <datatype>[,column_error OUT NUMBER][,actual_length OUT INTEGER]);See final demoCOLUMN_VALUE_CHARReturns value of the cursor element for a given position in a cursor dbms_sql.column_value_char (c IN INTEGER,position IN INTEGER,value OUT CHAR CHARACTER SET ANY_CS[,column_error OUT NUMBER][,actual_length OUT INTEGER]);See column_value in final demoCOLUMN_VALUE_LONGReturns a selected part of a LONG column, that has been defined using DEFINE_COLUMN_LONG dbms_sql.column_value_long (c IN INTEGER,position IN INTEGER,length IN INTEGER,offset IN INTEGER,value OUT VARCHAR2,value_length OUT INTEGER);See column_value in final demoCOLUMN_VALUE_RAWReturns value of the cursor element for a given position in a cursor dbms_sql.column_value_raw (c IN INTEGER,position IN INTEGER,value OUT RAW[,column_error OUT NUMBER][,actual_length OUT INTEGER]);See column_value in final demoCOLUMN_VALUE_ROWIDUndoc dbms_sql.column_value_rowid (c IN INTEGER,position IN INTEGER,value OUT ROWID[,column_error OUT NUMBER][,actual_length OUT INTEGER]);See column_value in final demoDEFINE_ARRAYDefines a collection to be selected from the given cursor, used only with SELECT statements dbms_sql.define_array (c IN INTEGER,position IN INTEGER,<table_variable> IN <datatype>cnt IN INTEGER,lower_bnd IN INTEGER);DECLAREc number;d number;n_tab dbms_sql.number_table;indx number := -10;BEGINc := dbms_sql.open_cursor;dbms_sql.parse(c,'select n from t order by 1',dbms_sql.NATIVE);dbms_sql.define_array(c, 1, n_tab, 10, indx);d := dbms_sql.execute(c);LOOPd := dbms_sql.fetch_rows(c);dbms_sql.column_value(c, 1, n_tab);exit when d != 10;END LOOP;dbms_sql.close_cursor(c);EXCEPTIONSWHEN OTHERS THENIF dbms_sql.is_open(c) THENdbms_sql.close_cursor(c);END IF;RAISE;END;/DEFINE_COLUMNDefines a column to be selected from the given cursor, used only with SELECT statements dbms_sql.define_column (c IN INTEGER,position IN INTEGER,column IN <datatype>)See final demoDEFINE_COLUMN_CHARUndoc dbms_sql.define_column_char (c IN INTEGER,position IN INTEGER,column IN CHAR CHARACTER SET ANY_CS,column_size IN INTEGER);See define_column in final demoDEFINE_COLUMN_LONGDefines a LONG column to be selected from the given cursor, used only with SELECT statements dbms_sql.define_column_long (c IN INTEGER,position IN INTEGER);See define_column in final demoDEFINE_COLUMN_RAWUndoc dbms_sql.define_column_raw (c IN INTEGER,position IN INTEGER,column IN RAW,column_size IN INTEGER);See define_column in final demoDEFINE_COLUMN_ROWIDUndoc dbms_sql.define_column_rowid (c IN INTEGER,position IN INTEGER,column IN ROWID);See define_column in final demoDESCRIBE_COLUMNSDescribes the columns for a cursor opened and parsed through DBMS_SQL dbms_sql.describe_columns (c IN INTEGER,col_cnt OUT INTEGER,desc_t OUT DESC_TAB);DECLAREc NUMBER;d NUMBER;col_cnt PLS_INTEGER;f BOOLEAN;rec_tab dbms_sql.desc_tab;col_num NUMBER;PROCEDURE print_rec(rec in dbms_sql.desc_rec) ISBEGINdbms_output.new_line;dbms_output.put_line('col_type = '|| rec.col_type);dbms_output.put_line('col_maxlen = '|| rec.col_max_len);dbms_output.put_line('col_name = '|| rec.col_name);dbms_output.put_line('col_name_len = '|| rec.col_name_len);dbms_output.put_line('col_schema_name = '|| rec.col_schema_name);dbms_output.put_line('col_schema_name_len = '|| rec.col_schema_name_len);dbms_output.put_line('col_precision = '|| rec.col_precision);dbms_output.put_line('col_scale = '|| rec.col_scale);dbms_output.put('col_null_ok = ');if (rec.col_null_ok) thendbms_output.put_line('true');elsedbms_output.put_line('false');END IF;END;BEGINc := dbms_sql.open_cursor;dbms_sql.parse(c, 'select * from scott.bonus', dbms_sql.NATIVE);d := dbms_sql.execute(c);dbms_sql.describe_columns(c, col_cnt, rec_tab);/** Following loop could simply be for j in 1..col_cnt loop.* Here we are simply illustrating some of the PL/SQL table* features.*/col_num := rec_tab.first;IF (col_num IS NOT NULL) THENLOOPprint_rec(rec_tab(col_num));col_num := rec_tab.next(col_num);EXIT WHEN (col_num is null);END LOOP;END IF;dbms_sql.close_cursor(c);end;/DESCRIBE_COLUMNS2Describes the specified column, an alternative method dbms_sql.describe_columns2 ( c IN INTEGER,col_cnt OUT INTEGER,desc_tab2 OUT DESC_TAB);Why? ResearchEXECUTEExecute dynamic SQL cursor dbms_sql.execute(c IN INTEGER) RETURN INTEGER; DECLAREsqlstr VARCHAR2(50);tCursor PLS_INTEGER;RetVal NUMBER;BEGINsqlstr := 'DROP SYNONYM my_synonym';tCursor := dbms_sql.open_cursor;dbms_sql.parse(tCursor, sqlstr, dbms_sql.NATIVE);RetVal := dbms_sql.execute(tCursor);dbms_sql.close_cursor(tCursor);END;/EXECUTE_AND_FETCHExecutes a given cursor and fetch rows dbms_sql.execute_and_fetch(c IN INTEGER, exact IN BOOLEAN DEFAULT FALSE) RETURN INTEGER;Combine demo w/ last_row_count and last_row_id demosFETCH_ROWSFetches a row from a given cursor dbms_sql.fetch_rows(c IN INTEGER) RETURN INTEGER; See final demoIS_OPENDetermine whether a cursor is open dbms_sql.is_open(c IN INTEGER) RETURN BOOLEAN; set serveroutput onDECLAREtCursor PLS_INTEGER;BEGINtCursor := dbms_sql.open_cursor;IF dbms_sql.is_open(tCursor) THENdbms_output.put_line('1-OPEN');ELSEdbms_output.put_line('1-CLOSED');END IF;dbms_sql.close_cursor(tCursor);IF dbms_sql.is_open(tCursor) THENdbms_output.put_line('2-OPEN');ELSEdbms_output.put_line('2-CLOSED');END IF;END;/LAST_ERROR_POSITIONReturns byte offset in the SQL statement text where the error occurred dbms_st_error_position RETURN INTEGER;LAST_ROW_COUNTReturns cumulative count of the number of rows fetched dbms_st_row_count RETURN INTEGER;LAST_ROW_IDReturns ROWID of last row processed dbms_st_row_id RETURN ROWID;LAST_SQL_FUNCTION_CODEReturns SQL function code for statement dbms_st_sql_function_code RETURN INTEGER;OPEN_CURSOROpen dynamic SQL cursor and return cursor ID number of new cursor dbms_sql.open_cursor RETURN INTEGER;See is_open demoPARSEParse statementOverload 1 dbms_sql.parse(<cursor_variable>, <sql_string>,dbms_sql.NATIVE);CREATE SYNONYM test_syn FOR dual;SELECT *FROM test_syn;SELECT synonym_nameFROM user_synonyms;DECLAREsqlstr VARCHAR2(50);tCursor PLS_INTEGER;BEGINsqlstr := 'DROP SYNONYM test_syn';tCursor := dbms_sql.open_cursor;dbms_sql.parse(tCursor, sqlstr, dbms_sql.NATIVE);dbms_sql.close_cursor(tCursor);END;/SELECT synonym_nameFROM user_synonyms;-- with returning clausecreate or replace procedure single_Row_insert(c1 number, c2 number, r out number) isc number;n number;beginc := dbms_sql.open_cursor;dbms_sql.parse(c, 'insert into tab values (:bnd1, :bnd2) ' ||'returning c1*c2 into :bnd3', 2);dbms_sql.bind_variable(c, 'bnd1', c1);dbms_sql.bind_variable(c, 'bnd2', c2);dbms_sql.bind_variable(c, 'bnd3', r);n := dbms_sql.execute(c);dbms_sql.variable_value(c, 'bnd3', r); -- get value of outbind variable dbms_Sql.close_Cursor(c);end;/Parse statementOverload 2 dbms_sql.parse(c IN INTEGER,statement IN VARCHAR2A,lb IN INTEGER,ub IN INTEGER,lfflg IN BOOLEAN,language_flag IN INTEGER);Parse statementOverload 3 dbms_sql.parse(c IN INTEGER,statement IN VARCHAR2S,lb IN INTEGER,ub IN INTEGER,lfflg IN BOOLEAN,language_flag IN INTEGER);VARIABLE_VALUEReturns value of named variable for given cursorOverload 1 dbms_sql.variable_value(c IN INTEGER,name IN VARCHAR2,value OUT <datatype>);Returns value of named variable for given cursorOverload 2 dbms_sql.variable_value(c IN INTEGER,name IN VARCHAR2,<table_varaible> IN <datatype>);VARIABLE_VALUE_CHARUndoc dbms_sql.variable_value_char(c IN INTEGER,name IN VARCHAR2,value OUT CHAR CHARACTER SET ANY_CS);VARIABLE_VALUE_RAWUndoc dbms_sql.variable_value_raw(c IN INTEGER,name IN VARCHAR2,value OUT RAW);VARIABLE_VALUE_ROWIDUndoc dbms_sql.variable_value_rowid(c IN INTEGER,name IN VARCHAR2,value OUT ROWID);DemosDrop Synonym Demo SELECT synonym_nameFROM user_synonyms;CREATE SYNONYM d FOR dept;CREATE SYNONYM e FOR emp;SELECT synonym_nameFROM user_synonyms;CREATE OR REPLACE PROCEDURE dropsyn ISCURSOR syn_cur ISSELECT synonym_nameFROM user_synonyms;RetVal NUMBER;sqlstr VARCHAR2(200);tCursor PLS_INTEGER;BEGINFOR syn_rec IN syn_curLOOPsqlstr := 'DROP SYNONYM ' || syn_rec.synonym_name;tCursor := dbms_sql.open_cursor;dbms_sql.parse(tCursor, sqlstr, dbms_sql.NATIVE);RetVal := dbms_sql.execute(tCursor);dbms_sql.close_cursor(tCursor);END LOOP;EXCEPTIONWHEN OTHERS THENRAISE;END dropsyn;/exec dropsyn;SELECT synonym_nameFROM user_synonyms;Executing CLOBS Demo Tables CREATE TABLE workstations ( srvr_id NUMBER(10),ws_id NUMBER(10),location_id NUMBER(10),cust_id VARCHAR2(15),status VARCHAR2(1),latitude FLOAT(20),longitude FLOAT(20),netaddress VARCHAR2(15))TABLESPACE data_sml;CREATE TABLE test (test NUMBER(10));Run Demo CREATE OR REPLACE PROCEDURE execute_plsql_block( plsql_code_block CLOB) ISds_cur PLS_INTEGER := dbms_sql.open_cursor;sql_table dbms_sql.VARCHAR2S;c_buf_len CONSTANT BINARY_INTEGER := 256;v_accum INTEGER := 0;v_beg INTEGER := 1;v_end INTEGER := 256;v_loblen PLS_INTEGER;v_RetVal PLS_INTEGER;----------------------------- local function to the execute_plsql_block procedure FUNCTION next_row (clob_in IN CLOB,len_in IN INTEGER,off_in IN INTEGER) RETURN VARCHAR2 ISBEGINRETURN DBMS_LOB.SUBSTR(clob_in, len_in, off_in); END next_row;---------------------------BEGINv_loblen := DBMS_LOB.GETLENGTH(plsql_code_block);INSERT INTO test VALUES (v_loblen);COMMIT;LOOP-- Set the length to the remaining size-- if there are < c_buf_len characters remaining. IF v_accum + c_buf_len > v_loblen THENv_end := v_loblen - v_accum;END IF;sql_table(NVL(sql_ST, 0) + 1) :=next_row(plsql_code_block, v_end, v_beg);v_beg := v_beg + c_BUF_LEN;v_accum := v_accum + v_end;IF v_accum >= v_loblen THENEXIT;END IF;END LOOP;-- Parse the pl/sql and execute itdbms_sql.parse(ds_cur, sql_table, sql_table.FIRST, sql_ST, FALSE, dbms_sql.NATIVE);v_RetVal := dbms_sql.execute(ds_cur);dbms_sql.close_cursor(ds_cur);END execute_plsql_block;/Executing CLOBS Demo Data DECLAREclob_in CLOB;BEGINclob_in := CAST('BEGININSERT INTO WORKSTATIONS VALUES (1,1,20075,'''',''Y'',32.97948,-117.2569,''''); INSERT INTO WORKSTATIONS VALUES (1,10,20077,'''',''N'',32.97125,-117.2675,''''); INSERT INTO WORKSTATIONS VALUES (1,11,20078,'''',''N'',33.03865,-96.83579,''''); INSERT INTO WORKSTATIONS VALUES (1,12,20079,'''',''Y'',32.97413,-117.2694,''10.128.48.121'');INSERT INTO WORKSTATIONS VALUES (1,2,20081,'''',''N'',32.97948,-117.2569,''''); INSERT INTO WORKSTATIONS VALUES (1,3,20082,'''',''Y'',32.97948,-117.2569,''10.128.0.1'');INSERT INTO WORKSTATIONS VALUES (1,4,20083,''15689'',''N'',32.98195,-117.2636,'''');INSERT INTO WORKSTATIONS VALUES (1,5,20085,'''',''Y'',32.98195,-117.2636,''10.128.16.105'');INSERT INTO WORKSTATIONS VALUES (1,6,20086,'''',''N'',32.97096,-117.2689,''''); INSERT INTO WORKSTATIONS VALUES (1,7,20077,'''',''Y'',32.97125,-117.2675,''10.128.48.105'');INSERT INTO WORKSTATIONS VALUES (1,8,20090,'''',''N'',32.97124,-117.2676,''''); INSERT INTO WORKSTATIONS VALUES (1,9,20092,'''',''N'',32.97023,-117.2688,''''); INSERT INTO WORKSTATIONS VALUES (10,1,20094,'''',''Y'',61.2224,-149.8047,''10.128.112.1'');INSERT INTO WORKSTATIONS VALUES (10,2,20095,'''',''N'',61.2224,-149.8047,''''); INSERT INTO WORKSTATIONS VALUES (10,3,20096,'''',''Y'',61.2224,-149.8047,''10.128.112.113'');INSERT INTO WORKSTATIONS VALUES (10,4,13545,'''',''Y'',61.14104,-149.9519,''10.128.112.121'');INSERT INTO WORKSTATIONS VALUES (10,5,20104,'''',''N'',61.2224,-149.8047,''''); INSERT INTO WORKSTATIONS VALUES (10,6,20106,'''',''Y'',61.21685,-149.8002,''10.128.80.113'');INSERT INTO WORKSTATIONS VALUES (11,1,20110,'''',''N'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,10,20113,'''',''N'',61.14104,-149.9519,''''); INSERT INTO WORKSTATIONS VALUES (11,11,20116,'''',''N'',61.14104,-149.9519,''''); INSERT INTO WORKSTATIONS VALUES (11,12,20117,'''',''Y'',61.137,-149.9395,''10.128.32.193'');INSERT INTO WORKSTATIONS VALUES (11,13,20118,'''',''Y'',61.137,-149.9395,''10.128.16.129'');INSERT INTO WORKSTATIONS VALUES (11,14,20119,'''',''Y'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,15,20121,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,16,20122,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,17,13545,'''',''Y'',61.14104,-149.9519,'''');INSERT INTO WORKSTATIONS VALUES (11,18,19922,'''',''Y'',61.13549,-149.959,''10.128.48.153'');INSERT INTO WORKSTATIONS VALUES (11,19,19923,'''',''N'',61.13422,-149.962,''''); INSERT INTO WORKSTATIONS VALUES (11,2,19924,'''',''N'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,20,19925,'''',''N'',61.146,-149.9799,''''); INSERT INTO WORKSTATIONS VALUES (11,21,19926,'''',''N'',61.146,-149.9799,''''); INSERT INTO WORKSTATIONS VALUES (11,22,19927,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,23,19928,'''',''N'',61.14104,-149.9519,''''); INSERT INTO WORKSTATIONS VALUES (11,24,19930,'''',''N'',61.13422,-149.962,''''); INSERT INTO WORKSTATIONS VALUES (11,25,19931,'''',''N'',61.13678,-149.9644,''''); INSERT INTO WORKSTATIONS VALUES (11,26,20033,'''',''N'',61.14477,-149.9586,''''); INSERT INTO WORKSTATIONS VALUES (11,27,20034,'''',''N'',61.13466,-149.975,''''); INSERT INTO WORKSTATIONS VALUES (11,28,20035,'''',''N'',61.14142,-149.9668,''''); INSERT INTO WORKSTATIONS VALUES (11,29,20036,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,3,20037,'''',''Y'',61.137,-149.9395,''10.128.16.105'');INSERT INTO WORKSTATIONS VALUES (11,30,20038,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,31,20039,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,32,20040,'''',''N'',61.13695,-149.9396,''''); INSERT INTO WORKSTATIONS VALUES (11,33,20042,'''',''N'',61.12887,-149.9578,''''); INSERT INTO WORKSTATIONS VALUES (11,4,20043,'''',''N'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,5,20044,'''',''Y'',61.137,-149.9395,''10.128.32.129'');INSERT INTO WORKSTATIONS VALUES (11,6,20045,'''',''N'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,7,20046,'''',''N'',61.137,-149.9395,''''); INSERT INTO WORKSTATIONS VALUES (11,8,20047,'''',''N'',61.137,-149.9395,'''');--====INSERT INTO WORKSTATIONS VALUES (11,9,20048,'''',''Y'',61.137,-149.9395,''10.128.32.169'');INSERT INTO WORKSTATIONS VALUES (12,1,20051,''15706'',''Y'',32.75604,-117.1201,'''');INSERT INTO WORKSTATIONS VALUES (12,10,20053,'''',''N'',32.75689,-117.12,''''); INSERT INTO WORKSTATIONS VALUES (12,100,20054,'''',''N'',32.7596,-117.124,''''); INSERT INTO WORKSTATIONS VALUES (12,101,20056,'''',''N'',32.75689,-117.129,''''); INSERT INTO WORKSTATIONS VALUES (12,102,20057,'''',''Y'',32.75677,-117.1241,''10.129.112.25'');INSERT INTO WORKSTATIONS VALUES (12,103,20058,'''',''Y'',32.75662,-117.124,''10.129.112.33'');INSERT INTO WORKSTATIONS VALUES (12,104,20060,'''',''N'',32.7571,-117.1242,''''); INSERT INTO WORKSTATIONS VALUES (12,105,20061,'''',''N'',32.75316,-117.1253,''''); INSERT INTO WORKSTATIONS VALUES (12,106,20063,'''',''N'',32.76154,-117.1251,''''); --====COMMIT;END;' AS CLOB);。
oracle动态sql语句

oracle动态sql语句Oracle动态SQL语句是一种在运行时生成SQL语句的技术。
它允许用户根据不同的条件和需求,动态地构建SQL语句,从而实现更灵活、更高效的数据操作。
在实际应用中,动态SQL语句被广泛应用于数据查询、数据更新、数据删除等方面。
动态SQL语句的优点在于它可以根据不同的条件和需求,动态地生成SQL语句。
这样可以大大提高SQL语句的灵活性和可重用性。
例如,当用户需要查询某个表中的数据时,可以根据不同的查询条件动态生成SQL语句,从而实现更精确的数据查询。
此外,动态SQL语句还可以避免SQL注入攻击,提高系统的安全性。
在Oracle数据库中,动态SQL语句可以通过使用EXECUTE IMMEDIATE语句来实现。
该语句可以接受一个字符串参数,该参数包含要执行的SQL语句。
例如,以下代码演示了如何使用EXECUTE IMMEDIATE语句来查询一个表中的数据:DECLAREv_sql VARCHAR2(200);v_empno NUMBER := 7369;v_ename VARCHAR2(20);BEGINv_sql := 'SELECT ename FROM emp WHERE empno = :1';EXECUTE IMMEDIATE v_sql INTO v_ename USING v_empno;DBMS_OUTPUT.PUT_LINE('Employee name: ' || v_ename); END;在上面的代码中,首先定义了一个字符串变量v_sql,该变量包含要执行的SQL语句。
然后,使用EXECUTE IMMEDIATE语句执行该SQL语句,并将查询结果存储在变量v_ename中。
最后,使用DBMS_OUTPUT.PUT_LINE语句将查询结果输出到控制台。
除了使用EXECUTE IMMEDIATE语句外,Oracle数据库还提供了其他一些动态SQL语句的实现方式,例如使用DBMS_SQL包、使用REF CURSOR等。
oracle sql查询ddl语句

一、DDL语句的作用DDL(Data Definition Language,数据定义语言)是用来定义数据库对象的语言,包括创建、修改和删除数据库中的对象,例如表、视图、索引等。
Oracle SQL是一种使用DDL语句来管理数据库的数据库语言,通过使用DDL语句可以轻松地对数据库结构进行管理和维护。
二、DDL语句的分类1. 创建表在Oracle SQL中,使用CREATE TABLE语句可以创建数据库中的表。
例如:```CREATE TABLE employees (id number(10),name varchar2(50),age number(3),salary number(12, 2));```以上语句创建了一个名为employees的表,包括id、name、age和salary四个字段。
2. 修改表结构使用ALTER TABLE语句可以修改现有表的结构,例如增加字段、修改字段类型、删除字段等。
例如:```ALTER TABLE employeesADD department varchar2(50);```以上语句向employees表中新增了一个名为department的字段。
3. 删除表DROP TABLE语句可以用来删除数据库中的表,例如:```DROP TABLE employees;```以上语句删除了名为employees的表。
4. 创建索引CREATE INDEX语句用来创建数据库表的索引,以加快对表中数据的检索速度。
例如:```CREATE INDEX idx_name ON employees (name);```以上语句创建了一个名为idx_name的索引,用于employees表中的name字段。
5. 创建视图CREATE VIEW语句可以创建数据库中的视图,用于展示数据库表的部分数据。
例如:```CREATE VIEW high_salary_employees ASSELECT id, name, salaryFROM employeesWHERE salary > xxx;```以上语句创建了一个名为high_salary_employees的视图,用于展示employees表中薪水大于xxx的雇员信息。
【转】Oracle执行动态语句

【转】Oracle执⾏动态语句1.静态SQLSQL与动态SQLOracle编译PL/SQL程序块分为两个种:其⼀为前期联编(early binding),即SQL语句在程序编译期间就已经确定,⼤多数的编译情况属于这种类型;另外⼀种是后期联编(late binding),即SQL语句只有在运⾏阶段才能建⽴,例如当查询条件为⽤户输⼊时,那么Oracle的SQL 引擎就⽆法在编译期对该程序语句进⾏确定,只能在⽤户输⼊⼀定的查询条件后才能提交给SQL引擎进⾏处理。
通常,静态SQL采⽤前⼀种编译⽅式,⽽动态SQL采⽤后⼀种编译⽅式。
2.动态SQL程序开发理解了动态SQL编译的原理,也就掌握了其基本的开发思想。
动态SQL既然是⼀种”不确定”的SQL,那其执⾏就有其相应的特点。
Oracle中提供了Execute immediate语句来执⾏动态SQL,语法如下:Excute immediate 动态SQL语句 using 绑定参数列表 returning into输出参数列表;1)动态SQL是指DDL和不确定的DML(即带参数的DML)2)绑定参数列表为输⼊参数列表,即其类型为in类型,在运⾏时刻与动态SQL语句中的参数(实际上占位符,可以理解为函数⾥⾯的形式参数)进⾏绑定。
3)输出参数列表为动态SQL语句执⾏后返回的参数列表。
4)由于动态SQL是在运⾏时刻进⾏确定的,所以相对于静态⽽⾔,其更多的会损失⼀些系统性能来换取其灵活性。
设数据库的emp表,其数据为如下:ID NAME SALARY100Jacky5600101Rose3000102John4500要求:1.创建该表并输⼊相应的数据。
2.根据特定ID可以查询到其姓名和薪⽔的信息。
3.根据⼤于特定的薪⽔的查询相应的员⼯信息。
根据前⾯的要求,可以分别创建三个过程(均使⽤动态SQL)来实现:过程⼀:1create or replace procedure create_table is2begin3execute immediate ' create table emp(4id number,5name varchar2(10),6salary number )'; --动态SQL为DDL语句7end create_table;过程⼆:1create or replace procedure find_info(p_id number) i s2 v_name varchar2(10);3 v_salary number;4begin5execute immediate '6select name,salary from emp7where id=:1'8 using p_id9 returning into v_name,v_salary; --动态SQL为查询语句10 dbms_output.put_line(v_name ||'的收⼊为:'||to_char(v_salary));11 exception12when others then13 dbms_output.put_line('找不到相应数据');14end find_info;过程三:1create or replace procedure find_emp(p_salary number) i s2 r_emp emp%rowtype;3 type c_type is ref cursor;4 c1 c_type;5begin6open c1 for'7select * from emp8where salary >:1'9 using p_salary;10 loop11fetch c1 into r_emp;12exit when c1%notfound;13 dbms_output.put_line('薪⽔⼤于‘||to_char(p_salary)||'的员⼯为:‘);14 dbms_output.put_line('ID为'to_char(r_emp)||' 其姓名为:'||r_);15end loop;16close c1;17end create_table;注意:在过程⼆中的动态SQL语句使⽤了占位符“:1“,其实它相当于函数的形式参数,使⽤”:“作为前缀,然后使⽤using语句将p_id在运⾏时刻将:1给替换掉,这⾥p_id相当于函数⾥的实参。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
如果你用的是Oracle8i 及以上的版本,那简单,在过程中用 execute immediate sql_str 就行, sql_str 是一个拼凑的 SQL 语句,但这个动态语句中带参数,或 Select 的结果要 into 到变量中时就要稍加留心一下了。
而在 8i 以前的版本(谁还用这么古老的玩艺,总有些不得已的地方,老系统考虑升级成本遗留下来的,应用软件所伴随着的等),都没法用 execute immediate,就得使用 DBMS_SQL 包来实现了
何谓动态 SQL 和 DDL 语句呢?通常在过程中要操作的表名、字段名都必须是明确的,否则编译过程时就要报错,但如果这两者也用变量名来表示就是动态的。
DDL 就是数据库对象定义的操作,如 CREATE TABLE/VIEW/INDEX/SYN/CLUSTER……,及这些对象的删除、修改操作等等。
比如在Oracle中有执行下面过程块的意图时,就要使用到 execute immediate 或是DBMS_SQL 包了。
当然下面的语句块是通不过的。
declare
col_name varchar2(30) := 'name'; --假定表user存在name字段
col_val varchar2(30);
begin
select col_name into col_val --按照惯常思维,可能就会这么写
from user where age between 18 and 25; --编译时会提示列名不存在的
drop table t2; --不能直接执行 DDL 语句,后面查询 t2 编译器就无能为力了
end;
现在我们提出对上面问题的解,针对第一个 Select 语句来说明,并假设查询中还带有参数。
块中的 DDL 也是类似的解法。
例子因力图涵盖更多内容,所以稍显复杂,如果不需要 into (如 update/delete 语句),或者不带参数,会简单多了,应不难简化。
有两种处理方法,以 8i 为分水岭。
1. Oracle 8i 及以上版本的过程中处理动态 SQL 语句的办法
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;
除此之外,在 Oracle 8i 及以上版本中,还能用 DBMS_UTILITY.EXEC_DDL_STATEMENT (ddl_sql_str)执行 DDL 语句。
2. Oracle 8i 以下版本相应解决之道,用 DBMS_SQL 包,如 Oracle 8.0.5 中
如果也用 execute immediate 的话编译过程时就会报如下错误:
Error: PLS-00103:出现符号"IMMEDIATE"在需要下列之一时:
:=.(@%;
符号":=在"IMMEDIATE"继续之前已插入。
Line: 3
declare
v_col_name varchar2(30) := 'name'; --字段名 name 用变量来表示
v_user_name varchar2(30); --用户名称
v_user_age integer; --用户年龄
v_sql_str varchar2(500); --动态 SQL 语句
v_cursorid integer; --游标 ID
v_dummy integer; --定义一个哑元变量
begin
v_sql_str := 'select '||v_col_name||',age from users --字段名后面不能紧随 into 到变量了
where age between :start_age and :end_age'; --两个命名参数
v_cursorid := dbms_sql.open_cursor; -- 为处理打开光标
dbms_sql.parse(v_cursorid,v_sql_str,dbms_sql.NATIVE); -- 分析SQL字符串
dbms_sql.bind_variable(v_cursorid,'start_age',8); --绑定变量 8 到 start_age
dbms_sql.bind_variable(v_cursorid,'end_age',25); --绑定变量 25 到 end_age
--定义输出的列,1为第1列,v_col_name任意,30是宽度,对于是VARCHAR2,CHAR类型要指定列宽
dbms_sql.define_column(v_cursorid,1,v_col_name,30);
dbms_sql.define_column(v_cursorid,2,v_user_age); --定义第2列,数字类型,无须指定列宽
--也可用 execute_and_fetch 执行后立即 fetch 第一行,其后还能 fetch_rows获取其余记录 v_dummy := dbms_sql.execute(v_cursorid); --执行语句,
while(dbms_sql.fetch_rows(v_cursorid)>0) --有记录时,fetch_rows 总是返回 1,否则为0 loop
dbms_sql.column_value(v_cursorid,1,v_user_name); --获取第一列的输出值
dbms_sql.column_value(v_cursorid,2,v_user_age); --获取第一列的输出值
dbms_output.put_line('符合条件的用户:'||v_user_name||',年龄:'||v_user_age);
end loop;
dbms_sql.close_cursor(v_cursorid); --关闭光标
end;
真的是很复杂啊,有条件还是赶紧升级你的数据库吧,越高越好。
当然,如果你只是用来执行一个简单的语句,没有参数,不在乎返回值的话,那也不是很费事。
需注意一个问题,在执行 dbms_sql.define_column()定义列时,如果指定了列宽,就会认为是字符串类型,并且编译时也要求字符串类型必须指定宽度。
在用
dbms_sql.column_value()接收输出值时必须符合前面的定义。
比如在定义第 2 列 age 时也加了列宽参数,如
dbms_sql.define_column(v_cursorid,2,v_user_age,10);——对于非字符串类型加了列宽参数也能编译通过,只是被误认为字符串
那在上面代码中接收这个字段值 dbms_sql.column_value(v_cursorid,2,v_user_age)时就会报类型不匹配的错误(ORA-06562:输出自变量的类型必须与列或赋值变量的类型匹配),因为前面定义该列时,加了列宽就被认为是字符串类型,不能用数字型的 v_user_age 接收该字段值。