通过不带管道的立即执行创建 Oracle 序列 ||操作员
Create Oracle sequence via execute immediate without pipe || operator
create sequence s1 ;
declare
v_value number;
v_sql_stmt varchar2(4000);
v_seq_name varchar2(30);
BEGIN
v_seq_name:='S1'; -- **this is dynamic and the sequence will be passed in the proc as input parameter at runtime**
v_sql_stmt:= 'select :v_seq_name'||'.nextval from dual' ;
EXECUTE IMMEDIATE v_sql_stmt INTO v_value USING v_seq_name ;
--**below is working but I dont want to do in this way because of sql injection issue, let me know how to fix the above**
--EXECUTE IMMEDIATE 'select ' || v_seq_name || '.nextval from dual' INTO v_value;
dbms_output.put_line(v_value);
end;
/
以上代码报错,请帮忙修复。
如果你 运行 注释代码那么它将 运行 但我不想使用 ||在立即执行。我只想使用冒号:。
序列名称将在 运行 时传递。上面的代码稍后会转化为proc。
我理解您对 SQL 注入的担忧。据我所知,无法使用绑定变量指定 table/column/sequence 名称。但是,您可以在执行不安全代码之前做一个简单的检查:
CREATE SEQUENCE s1;
CREATE SEQUENCE s2;
CREATE OR REPLACE FUNCTION p(seq_name VARCHAR2) RETURN NUMBER AS
v_value number;
v_sql_stmt varchar2(4000);
v_seq_name varchar2(128 BYTE);
BEGIN
v_seq_name:= DBMS_ASSERT.SIMPLE_SQL_NAME(seq_name);
v_sql_stmt:= 'select '||v_seq_name||'.nextval from dual';
EXECUTE IMMEDIATE v_sql_stmt INTO v_value;
RETURN v_value;
END p;
/
如果使用有效名称,一切都会按预期运行:
select p('s1') from dual;
1
select p('s2') from dual;
2
但是,如果 seq_name
不是有效的 Oracle 名称,DBMS_ASSERT
会抛出异常:
select p('1; DROP TABLE x') from dual;
ORA-44003: invalid SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 215
ORA-06512: at "WFL.P", line 6
44003. 0000 - "invalid SQL name"
create sequence s1 ;
declare
v_value number;
v_sql_stmt varchar2(4000);
v_seq_name varchar2(30);
BEGIN
v_seq_name:='S1'; -- **this is dynamic and the sequence will be passed in the proc as input parameter at runtime**
v_sql_stmt:= 'select :v_seq_name'||'.nextval from dual' ;
EXECUTE IMMEDIATE v_sql_stmt INTO v_value USING v_seq_name ;
--**below is working but I dont want to do in this way because of sql injection issue, let me know how to fix the above**
--EXECUTE IMMEDIATE 'select ' || v_seq_name || '.nextval from dual' INTO v_value;
dbms_output.put_line(v_value);
end;
/
以上代码报错,请帮忙修复。
如果你 运行 注释代码那么它将 运行 但我不想使用 ||在立即执行。我只想使用冒号:。
序列名称将在 运行 时传递。上面的代码稍后会转化为proc。
我理解您对 SQL 注入的担忧。据我所知,无法使用绑定变量指定 table/column/sequence 名称。但是,您可以在执行不安全代码之前做一个简单的检查:
CREATE SEQUENCE s1;
CREATE SEQUENCE s2;
CREATE OR REPLACE FUNCTION p(seq_name VARCHAR2) RETURN NUMBER AS
v_value number;
v_sql_stmt varchar2(4000);
v_seq_name varchar2(128 BYTE);
BEGIN
v_seq_name:= DBMS_ASSERT.SIMPLE_SQL_NAME(seq_name);
v_sql_stmt:= 'select '||v_seq_name||'.nextval from dual';
EXECUTE IMMEDIATE v_sql_stmt INTO v_value;
RETURN v_value;
END p;
/
如果使用有效名称,一切都会按预期运行:
select p('s1') from dual;
1
select p('s2') from dual;
2
但是,如果 seq_name
不是有效的 Oracle 名称,DBMS_ASSERT
会抛出异常:
select p('1; DROP TABLE x') from dual;
ORA-44003: invalid SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 215
ORA-06512: at "WFL.P", line 6
44003. 0000 - "invalid SQL name"