动态sql执行存储过程
实现的话,这个得看你需求才能写,一般语法也不是特别麻烦,多学学循环,动态sql的基本可以应付一切了。
执行的话,一般开个sql窗口
begin
存储过程名(参数1,参数2……);
end;如果没有参数,括号里一堆就不用写了,然后执行即可。
❷ 如何在oracle存储过程中执行动态sql语句
有时需要在oracle
存储过程中执行动态sql
语句
,例如表名是动态的,或字段是动态的,或查询命令是动态的,可用下面的方法:
set
serveroutput
on
declare
n
number;
sql_stmt
varchar2(50);
t
varchar2(20);
begin
execute
immediate
'alter
session
set
nls_date_format=''yyyymmdd''';
t
:=
't_'
||
sysdate;
sql_stmt
:=
'select
count(*)
from
'
||
t;
execute
immediate
sql_stmt
into
n;
dbms_output.put_line('the
number
of
rows
of
'
||
t
||
'
is
'
||
n);
end;
如果动态sql
语句
很长很复杂,则可用包装.
create
or
replace
package
test_pkg
is
type
cur_typ
is
ref
cursor;
procere
test_proc
(v_table
varchar2,t_cur
out
cur_typ);
end;
/
create
or
replace
package
body
test_pkg
is
procere
test_proc
(v_table
varchar2,t_cur
out
cur_typ)
is
sqlstr
varchar2(2000);
begin
sqlstr
:=
'select
*
from
'||v_table;
open
t_cur
for
sqlstr;
end;
end;
/
在oracle
中批量导入,导出和删除表名以某些字符开头的表
spool
c:\a.sql
select
'drop
table
'
||
tname
||
';'
from
tab
where
tname
like
't%';
spool
off
@c:\a
❸ plsql中如何执行存储过程
实现的方法和详细的操作步骤如下:
1、第一步,双击plsql图标进入登录界面,输入用户名和密码,然后传输数据库实例名称,如下图所示,然后进入下一步。
❹ 如何动态执行存储过程或函数
您好,很高兴为您解答。
/*动态执行存储过程DEMO*/
DECLARE
v_Procere_Name VARCHAR2(320); --存储过程名
v_Input_Parameter1 VARCHAR2(320); --传入参数1
v_Input_Parameter2 VARCHAR2(320); --传入参数2
v_Return_Int INTEGER; --接收返回值
v_Return_String VARCHAR2(320); --接收返回值
v_Sql_Str VARCHAR2(320); --动态执行SQL语句
BEGIN
/*获取存储过程名,可以从数据库中动态读取需要执行的存储过程,本DEMO直接赋值*/
v_Procere_Name := 'Wms_Application_Out_p.Application_Out_List_Refuse(:i_Str1,:i_Str2,_Return_Int,_Return_String)';
/*本DEMO假定需要调用的存储过程有两个传入参数和两个传出参数*/
v_Input_Parameter1 := 'test01'; --传入参数1,在实际应用中根据具体情况机型赋值
v_Input_Parameter2 := 'test01'; --传入参数2,在实际应用中根据具体情况机型赋值
/*动态生成需要执行存储过程的SQL语句*/
v_Sql_Str := 'BEGIN ' || v_Procere_Name || '; END;';
/*执行该SQL语句*/
EXECUTE IMMEDIATE v_Sql_Str
USING IN v_Input_Parameter1, IN v_Input_Parameter2, OUT v_Return_Int, OUT v_Return_String; --参数类型和传递顺序必须与存储过程中的保持一致
/*输出返回值*/
Dbms_Output.Put_Line(v_Return_Int || v_Return_String);
END;
/*动态执行函数DEMO*/
DECLARE
v_Function_Name VARCHAR2(320); --函数名
v_Input_Parameter1 VARCHAR2(320); --传入参数1
v_Return_String VARCHAR2(320); --接收返回值
v_Sql_Str VARCHAR2(320); --动态执行SQL语句
BEGIN
/*获取函数名,可以从数据库中动态读取需要执行的函数,本DEMO直接赋值*/
v_Function_Name := 'Return_Str_f(:i_Str1)';
/*本DEMO假定需要调用的函数有1个传入参数*/
v_Input_Parameter1 := 'test01'; --传入参数1,在实际应用中根据具体情况机型赋值
/*动态生成需要执行函数的SQL语句*/
v_Sql_Str := 'begin :v_Return_String := ' || v_Function_Name || '; end;';
/*执行该SQL语句*/
EXECUTE IMMEDIATE v_Sql_Str
USING OUT v_Return_String, IN v_Input_Parameter1; --接收返回值必须在前,传入参数类型和传递顺序必须与函数中保持一致
/*输出返回值*/
Dbms_Output.Put_Line(v_Return_String);
END;
/*所调用函数*/
CREATE OR REPLACE FUNCTION Return_Str_f(i_Str1 VARCHAR2) RETURN VARCHAR2 IS
v_Sql_Str VARCHAR2(320);
v_Str1 VARCHAR2(320);
BEGIN
/*生成动态执行SQL*/
v_Sql_Str := 'SELECT ''' || i_Str1 || ''' FROM DUAL';
EXECUTE IMMEDIATE v_Sql_Str
INTO v_Str1; --接收返回值
/*输出返回结果*/
Dbms_Output.Put_Line('v_str1=' || v_Str1);
RETURN v_Str1;
END;
相关资料:
Oracle PL/SQL中动态执行SQL EXECUTE IMMEDIATE
在plsql中经常遇到sql语句是在过程中动态生成的,这个时候可以用EXECUTE IMMEDIATE来执行生成的sql语句。转一个javaeye(貌似他也是转的,找不到出处)上的EXECUTE IMMEDIATE用法。
EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析并马上执行动态的SQL语句或非运行时创建的PL/SQL块.动态创建和执行SQL语句性能超前,EXECUTE IMMEDIATE的目标在于减小企业费用并获得较高的性能,较之以前它相当轻易编码.尽管DBMS_SQL仍然可用,
但是推荐使用EXECUTE IMMEDIATE,因为它获的收益在包之上。
使用技巧
1. EXECUTE IMMEDIATE将不会提交一个DML事务执行,应该显式提交
假如通过EXECUTE IMMEDIATE处理DML命令,那么在完成以前需要显式提交或者作为EXECUTE IMMEDIATE自己的一部分. 假如通过EXECUTE IMMEDIATE处理DDL命令,它提交所有以前改变的数据
2. 不支持返回多行的查询,这种交互将用临时表来存储记录(参照例子如下)或者用REF cursors.
3. 当执行SQL语句时,不要用分号,当执行PL/SQL块时,在其尾部用分号.
4. 在Oracle手册中,未具体覆盖这些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能给你带来方便.
5. 对于Forms开发者,当在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.
EXECUTE IMMEDIATE用法例子
1. 在PL/SQL运行DDL语句
begin
execute immediate 'set role all';
end;
2. 给动态语句传值(USING 子句)
declare
l_depnam varchar2(20) := 'testing';
l_locvarchar2(10) := 'Du';
begin
execute immediate 'insert into dept values(:1, :2, :3)'
using 50, l_depnam, l_loc;
commit;
end;
3. 从动态语句检索值(INTO子句)
declare
l_cntvarchar2(20);
begin
execute immediate 'select count(1) from emp'
into l_cnt;
dbms_output.put_line(l_cnt);
end;
4. 动态调用例程.例程中用到的绑定变量参数必须指定参数类型.黓认为IN类型,其它类型必须显式指定
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cntnumber;
l_status varchar2(200);
begin
execute immediate 'begin ' l_routin '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
5. 将返回值传递到PL/SQL记录类型;同样也可用%rowtype变量
declare
type empdtlrec is record (empnonumber(4),
enamevarchar2(20),
deptnonumber(2));
empdtl empdtlrec;
begin
execute immediate 'select empno, ename, deptno '
'from emp where empno = 7934'
into empdtl;
end;
6. 传递并检索值.INTO子句用在USING子句前
declare
l_deptpls_integer := 20;
l_nam varchar2(20);
l_loc varchar2(20);
begin
execute immediate 'select dname, loc from dept where deptno = :1'
into l_nam, l_loc
using l_dept ;
end;
7. 多行查询选项.对此选项用insert语句填充临时表,用临时表进行进一步的处理,也可以用REF cursors纠正此缺憾.
declare
l_sal pls_integer := 2000;
begin
execute immediate 'insert into temp(empno, ename) '
'select empno, ename from emp '
'wheresal :1'
using l_sal;
commit;
end;
对于处理动态语句,EXECUTE IMMEDIATE比以前可能用到的更轻易并且更高效.当意图执行动态语句时,适当地处理异常更加重要.应该关注于捕捉所有可能的异常.
如若满意,请点击右侧【采纳答案】,如若还有问题,请点击【追问】
希望我的回答对您有所帮助,望采纳!
~ O(∩_∩)O~
❺ 存储过程含有动态SQL,与静态SQL有什么差别
SQL 语句从编译和运行的角度可以分为两种,静态 SQL和 动态 SQL,这两种 SQL 在使用方式、运行机制和性能表现等方面各有特点 :
静态 SQL:静态 SQL 语句一般用于嵌入式 SQL 应用中,在程序运行前,SQL 语句必须是确定的,例如 SQL 语句中涉及的列名和表名必须是存在的。静态 SQL 语句的编译是在应用程序运行前进行的,编译的结果会存储在数据库内部。而后程序运行时,数据库将直接执行编译好的 SQL 语句,降低运行时的开销。
动态 SQL:动态 SQL 语句是在应用程序运行时被编译和执行的,例如,使用 DB2 的交互式工具 CLP 访问数据库时,用户输入的 SQL 语句是不确定的,因此 SQL 语句只能被动态地编译。动态 SQL 的应用较多,常见的 CLI 和 JDBC 应用程序都使用动态 SQL。
静态sql:语句类型在编程时候必须是确定好的。比如
select * from employee where empno='abc'select * from employee where empno='12'都必须是确定的,唯一可以变化的是abc的值。
动态sql:语句类型可以在运行期间指定,比如clp就是最典型的动态sql程序,你可以输入任何命令。
静态sql的存取路径是在运行前就确定好的,而动态sql的存取路径是在运行时动态生成的。因此生成的存取计划相对更优,但考虑到生成存取路径的开销,有可能应用程序的运行时间相对会比静态sql长些。
❻ 存储过程中如何执行带输出参数的动态SQL
SQL Server存储过程中执行带输出参数的动态sql是很多人经常碰到的问题,比如根据一些条件查询列表,并返回记录数等。下面是一个参考示例,查询用户列表,它可以利用临时表实现翻页,并带有死锁和超时检测功能。 CREATE PRocere pUserList ( @UserType char(2), @pagenum int, @perpagesize int, @pagetotal int out, @rowcount int out ) as set nocount on DECLARE @Err INT,@ErrCounter INT declare @sql nvarchar(2000) --声明动态sql执行语句 declare @pagecount int --当前页数 declare @sWhere nvarchar(200) declare @sOrder nvarchar(100) set @sWhere = ' where 1=1 ' if not(@UserType is null) set @sWhere = @sWhere + ' and UserType = ' + @UserType set @sOrder = ' order by UserID ' --取得当前数据库的记录总数 declare @row_num int LockTimeOutRetry: --创建临时表,作为数据过滤 create table #change (T_id int) set @sql = 'select @row_num=count(*) from dbo.[User]' + @sWhere exec sp_executesql @sql,N'@row_num int output', @row_num output if @row_num % @perpagesize =0 set @pagetotal = @row_num/@perpagesize else set @pagetotal = @row_num/@perpagesize + 1 set @rowcount = @row_num if @row_num > @perpagesize begin set @row_num = @pagenum * @perpagesize if @row_num = @perpagesize begin set @sql = N'select top ' + cast(@perpagesize as varchar) + ' UserID,LoginName,RealName from dbo.[User]' + @sWhere + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end else begin set @row_num = (@pagenum-1) * @perpagesize set @pagecount = @row_num set @sql=N'insert #change (T_id) select top ' + cast(@pagecount as varchar) + ' UserID from dbo. [User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder exec sp_executesql @sql set @sql = N'select top ' + cast(@perpagesize as varchar) + ' UserID,LoginName,RealName from dbo.[User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end end else begin set @sql = 'select UserID,LoginName,RealName from dbo.[User]' + @sWhere + @sOrder exec sp_executesql @sql SET @Err = @@ERROR IF @Err <> 0 GOTO ErrorHandler return 0 end ErrorHandler: IF (@Err = 1222 OR @Err = 1205) AND @ErrCounter = 5 BEGIN RAISERROR ('Unable to Lock Data after five attempts.', 16,1) return -100 END IF @Err = 1222 OR @Err = 1205 -- Lock Timeout / Deadlock BEGIN WAITFOR DELAY '00:00:00.25' SET @ErrCounter = @ErrCounter + 1 GOTO LockTimeOutRetry END -- else unknown error RAISERROR (@err, 16,1) WITH LOG return -100 GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO
❼ 动态sql中如何执行 带参数的存储过程
exec
sp_executesql
@sqlGetCount,N'@Counts
int
out
',@Counts
out
实际上
就是通过这个sp_executesql来执行存储过程时,会定义变量
@Counts
,然后执行你的语句把值放到@Counts
里,最后返回。
另外,本质上这个和exec语句是一样的都是动态执行sql。
❽ 动态SQL语句与存储过程,谁有高见谢谢
如果你不写存储过程你有没想过会效率根低呢!
说白了你就是不明白存储过程!
在一个名称下存储并作为一个单元进行编译和处理的T-SQL 语句的集合。
在一个存储过程内,可以设计、编码、测试和执行某个常用任务所需的 SQL 语句和逻辑。之后,每个需要执行该任务的应用程序只须执行此存储过程即可。
允许模块化程序设计
对于需要重复执行的代码,执行效率更高
减少网络流量
可作为安全机制使用
好了如果你不用!那好我问你SQL注入你要怎么防止!
而且插入数据如果出现问题!数据会保存么!
这样你就会有那样这样的BAG出现!
存储过程为什么叫存储过程呢!
就是因为它预先把T-SQL语句存起来!在执行的时候系统会省掉很多缓存资源!
而且不会浪费资源!
假如有几百条的存储过程要写!又要计算!
那么为什么不可以在客户端实现一些这样又可以减轻SQL的负担!
现在的电脑配置能很高啦!问题一般出现不大!
界面验证呀!像一些简单的查询大可以在客户端实现么!
敏感数据在用存储过程计算!
我就做你说的那种第二种的开发!
效果也挺不错!
问题不在于存储过程!在于你代码的如何编写!
怎么样能够大大提高运行的效率!
例如不必要浪费的常量!开辟会占堆中资源!
有的代码运行次数太少!可以简写!甚至不写!非必要都可以省略!
4层架构知道吧!尽量的做到代码要重用!可大大减少资源的浪费!
SQL的负担也会腾出来许多!
扯远啦!
好了就这吧!
希望对你有帮助!
❾ 怎样SQL存储过程中执行动态SQL语句
1.EXEC的使用
EXEC命令有两种用法,一种是执行一个
存储过程
,另一种是执行一个动态的
批处理
。以下所讲的都是第二种用法。
下面先使用EXEC演示一个例子,代码1
DECLARE
@TableName
VARCHAR(50),@Sql
NVARCHAR
(MAX),@OrderID
INT;
SET
@TableName
=
'Orders';
SET
@OrderID
=
10251;
SET
@sql
=
'SELECT
*
FROM
'+QUOTENAME(@TableName)
+'WHERE
OrderID
=
'+
CAST(@OrderID
AS
VARCHAR(10))+'
ORDER
BY
ORDERID
DESC'
EXEC(@sql);
sp_executesql命令在SQL
Server中引入的比EXEC命令晚一些,它主要为重用执行计划提供更好的支持。
为了和EXEC作一个鲜明的对比,我们看看如果用代码1的代码,把EXEC换成sp_executesql,看看是否得到我们所期望的结果
DECLARE
@TableName
VARCHAR(50),@sql
NVARCHAR(MAX),@OrderID
INT
,@sql2
NVARCHAR(MAX);
SET
@TableName
=
'Orders
';
SET
@OrderID
=
10251;
SET
@sql
=
'SELECT
*
FROM
'+QUOTENAME(@TableName)
+
'
WHERE
OrderID
=
'+CAST(@OrderID
AS
VARCHAR(50))
+
'
ORDER
BY
ORDERID
DESC'
EXEC
sp_executesql
@sql
❿ oracle存储过程中如何执行动态SQL语句
有时需要在oracle 存储过程中执行动态SQL 语句 ,例如表名是动态的,或字段是动态的,或查询命令是动态的,可用下面的方法: set serveroutput on declare n number; sql_stmt varchar2(50); t varchar2(20); begin execute immediate 'alter session set nls_date_format=''YYYYMMDD'''; t := 't_' || sysdate; sql_stmt := 'select count(*) from ' || t; execute immediate sql_stmt into n; dbms_output.put_line('The number of rows of ' || t || ' is ' || n); end; 如果动态SQL 语句 很长很复杂,则可用包装. CREATE OR REPLACE PACKAGE test_pkg IS TYPE cur_typ IS REF CURSOR; PROCEDURE test_proc (v_table VARCHAR2,t_cur OUT cur_typ); END; / CREATE OR REPLACE PACKAGE BODY test_pkg IS PROCEDURE test_proc (v_table VARCHAR2,t_cur OUT cur_typ) IS sqlstr VARCHAR2(2000); BEGIN sqlstr := 'SELECT * FROM '||v_table; OPEN t_cur FOR sqlstr; END; END; / 在oracle 中批量导入,导出和删除表名以某些字符开头的表 spool c:\a.sql select 'drop table ' || tname || ';' from tab where tname like 'T%'; spool off @c:\a