这是一个让你可以在数据库为所欲为(自己成语接龙一下~~手动滑稽) 的语法
学计算机的我们必然是先知道怎么用,再知道为什么要这样用。先 know how ?再 know why?。
我目前也只知道怎么用,至于为什么,emmmm。超纲了超纲了。如果读者已经熟练掌握 execute immediate v_sql 的用法,那……很抱歉,阅读以上内容花费了您宝贵的时间。您去找其他博客看吧,顺便收下我的膝盖(扑通~~~)。
execute immediate (立即执行),它可以动态执行SQL。类似JavaScript中的 eval();
用法1
v_sql:='select * from sys_users';
execute immediate v_sql;
用法2
v_sql:='select count(*) from sys_users';
execute immediate v_sql into v_num;
用法3
v_sql:= ' select t.user_id FROM sys_users t where t.user_name = :1';
execute immediate v_sql into v_dname using v_item ;
用法4
v_sql := 'BEGIN :1 := ' || 'sys_users_pkg.get_user_id' || '(:2,:3,:4,:5);END;';
execute immediate v_sql using out v_user_id, in p_user_name, in p_password,
in p_parameter_other_1, p_parameter_other_2;
相当于在存储过程或函数中调用复杂过程给变量赋值
v_user_id := sys_users_pkg.get_user_id(p_user_name,p_password,...);
看到这里你肯定有很多疑问,如:
先看下我们sys_users表的数据
select * from sys_users;
execute immediate v_sql;
场景:将用户 “路人甲” (用户id=3) 的用户名更换为 “STT”
update sys_users t set t.user_name = ‘STT’ where t.user_id = 3
DECLARE
v_sql VARCHAR2(2000) := ''; --字符串变量,存储欲执行的SQL语句
BEGIN
v_sql := 'update sys_users t set t.user_name = '||'666'||' where t.user_id = 3';
EXECUTE IMMEDIATE v_sql;
END;
--
注意:执行以上匿名代码块此时我们还未提交数据,在其他session中是无法看到我们的修改,必须在同一个SQL窗口中执行以下SQL查询数据
select * from sys_users;
EXECUTE IMMEDIATE v_sql INTO 变量名;
场景:查询出sys_users表中的总行数 并赋值给变量 v_num
select count(*) from sys_users
DECLARE
v_sql VARCHAR2(2000) := ''; --执行的sql
v_num NUMBER := 0;
BEGIN
v_sql := 'select count(*) from sys_users';
-----------------------------------------
EXECUTE IMMEDIATE v_sql
INTO v_num;
dbms_output.put_line('execute immediate用法2 执行成功,员工总数:' || v_num);
END;
EXECUTE IMMEDIATE v_sql INTO v_user_id USING IN v_user_name;
场景:通过用户名查用户id
SELECT t.user_id FROM sys_users t WHERE t.user_name = ‘苏涛涛’;
DECLARE
v_sql VARCHAR2(2000) := ''; --执行的sql
v_user_name varchar2(10) := '苏涛涛';
v_user_id number :=0;
BEGIN
v_sql:= ' SELECT t.user_id FROM sys_users t WHERE t.user_name = :1';
execute immediate v_sql into v_user_id using v_user_name ;
dbms_output.put_line(v_user_name||'的用户id为:'||v_user_id);
END;
场景:在存储过程或函数或匿名块中 传入用户名、密码查出用户id
SELECT t.user_id FROM sys_users t WHERE t.user_name = ‘苏涛涛’ > AND t.password = ‘MD5(123)’;
在一个匿名块中调用一个写好的程序包
DECLARE
v_sql VARCHAR2(2000);
v_user_id NUMBER;
p_user_name VARCHAR2(20) := '苏涛涛';
p_password VARCHAR2(20) := 'MD5(123)';
--以下参数仅为了演示用法,无实际用途
p_parameter_other_1 VARCHAR2(20) := 'TEST1';
p_parameter_other_2 VARCHAR2(20) := 'TEST2';
p_parameter_other_3 VARCHAR2(20) := 'TEST3';
p_parameter_other_4 VARCHAR2(20) := 'TEST4';
BEGIN
v_sql := 'BEGIN :1 := ' || 'sys_users_pkg.get_user_id' || '(:2,:3,:4,:5,:6,:7);END;';
EXECUTE IMMEDIATE v_sql
USING OUT v_user_id, IN p_user_name, IN p_password,
IN p_parameter_other_1,
p_parameter_other_2,
p_parameter_other_3,
p_parameter_other_4;
dbms_output.put_line('用户名和密码均正确,此用户用户id为' || v_user_id);
END;
每日一句:最好的种树时间,一个是10年前,一个是现在。
--创建用户表(表名SYS_USERS) 多说一句:表名在Oracle数据库中不区分大小写
create table SYS_USERS
(
user_id NUMBER,
user_name VARCHAR2(100),
password VARCHAR2(100),
sex VARCHAR2(1),
enable_flag VARCHAR2(1)
);
--插入4条测试数据
insert into SYS_USERS (user_id, user_name, password, sex, enable_flag)
values (1, '苏涛涛', 'MD5(123)', 'F', 'Y');
insert into SYS_USERS (user_id, user_name, password, sex, enable_flag)
values (2, '宋文倩', 'MD5(MD5(456))', 'M', 'Y');
insert into SYS_USERS (user_id, user_name, password, sex, enable_flag)
values (3, '路人甲', '789', 'F', 'Y');
insert into SYS_USERS (user_id, user_name, password, sex, enable_flag)
values (4, '路人乙', '147', 'M', 'N');
CREATE OR REPLACE PACKAGE sys_users_pkg IS
FUNCTION get_user_id(p_user_name VARCHAR2
,p_password VARCHAR2
,p_parameter_other_1 VARCHAR2
,p_parameter_other_2 VARCHAR2
,p_parameter_other_3 VARCHAR2
,p_parameter_other_4 VARCHAR2) RETURN NUMBER;
END sys_users_pkg;
/
CREATE OR REPLACE PACKAGE BODY sys_users_pkg IS
FUNCTION get_user_id(p_user_name VARCHAR2
,p_password VARCHAR2
,p_parameter_other_1 VARCHAR2
,p_parameter_other_2 VARCHAR2
,p_parameter_other_3 VARCHAR2
,p_parameter_other_4 VARCHAR2) RETURN NUMBER IS
v_sql VARCHAR2(1000);
v_user_id NUMBER;
BEGIN
SELECT t.user_id
INTO v_user_id
FROM sys_users t
WHERE t.user_name = p_user_name
AND t.password = p_password;
RETURN v_user_id;
END;
END sys_users_pkg;
/