请问一个存储过程execute immediate的问题

CREATE OR REPLACE PROCEDURE INSERTAMOUNTTEST(v_region_code IN varchar2) IS
BEGIN
declare
v_sql varchar2(33);
begin
v_sql := 'update aaa set x =112 where region_code = 571';
[color=red] -- v_sql2 := 'update aaa set x = 6 where region_code = '''||v_region_code||'''';
-- v_sql3 := 'update aaa set x = 4 where region_code = '||v_region_code;[/color]
execute immediate v_sql;
commit;
end;
commit;
EXCEPTION
WHEN OTHERS THEN
commit;
END;

aaa表就是两个字段,一个number类型的x,还有一个varchar类型的region_code
上面我定义的三个v_sql任何一个都更新不了,execute immediate v_sql;没有执行就进入了异常块,实在不知道是为什么,谢谢,还有我想问下 v_sql2写法后面4个单引号还有前面3个单引号对吗

5个回答

[color=red]请问v_region_code后面的4个单引号代表什么意思啊[/color]

表示含有一个单引号(')的字符串

你定义的v_sql是varchar2(33),赋值的字符串都大于33了,能不报错吗

sql2正确啊,plsql中,字符串用俩个单音号表示的,如果你的字符串含有单引号,那么用两个单引号表示一个单引号,比如
[code="sql"]
v_region_code='571'
v_sql2 := 'update aaa set x = 6 where region_code = '''||v_region_code||'''';
把''替换成',那么直接执行的sql:
v_sql2 := 'update aaa set x = 6 where region_code = '571'
[/code]

你的代码写的不标准啊,好多commit,还没有rollback
[code="sql"]CREATE OR REPLACE PROCEDURE INSERTAMOUNTTEST(v_region_code IN VARCHAR2) IS
v_sql VARCHAR2(100);
BEGIN
-- 能直接sql,就不要用动态sql
UPDATE aaa
SET x = 7
WHERE region_code = v_region_code;

-- 使用绑定变量的动态sql,多使用在循环中,能够减少循环的开销.
v_sql := 'update aaa set x = 6 where region_code = :1';
EXECUTE IMMEDIATE v_sql USING v_region_code;

-- 就是动态sql了
v_sql := 'update aaa set x = 6 where region_code = ''' || v_region_code || '''';
EXECUTE IMMEDIATE v_sql;

COMMIT;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END;[/code]

v_sql2 是正确的;
如果
v_sql2 := 'update aaa set x = 6 where region_code = '||v_region_code||'';那么传进来的参数就是=571,571就不会带引号,所以这个传入的参数这里必须是三个引号,动态sql里是用两个引号表示一个单引号的。所以正确的应该是:
v_sql2 := 'update aaa set x = 6 where region_code = '''||v_region_code||'''';
另外,你的v_sql定义的太小,这样有可能就不会执行动态sql;

如果v_region_code传进来的是571,那么在动态语句v_sql2中
'''||v_region_code||'''的值就为'571'

这样你就把update aaa set x = 6 where region_code='571'赋给了动态语句
v_sql2;
这个update语句本身就是用''单引号引起来的,所以v_region_code后面的第四个单引号是跟update前面的这个单引号匹配的

把这个语句
update aaa set x = 6 where region_code = '''||v_region_code||''' 用单引号括起来
'update aaa set x = 6 where region_code = '''||v_region_code||''''

赋给v_sql2;

立即提问
相关内容推荐