Создать последовательность Oracle с помощью немедленного выполнения без конвейера || оператор - PullRequest
0 голосов
/ 05 мая 2020

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;
/

приведенный выше код вызывает ошибку, пожалуйста, помогите исправить.

Если вы запустите закомментированный код, он запустится, но я не хочу использовать || в исполнение немедленно. Я хочу использовать только двоеточие.

имя последовательности будет передано во время выполнения. Приведенный выше код будет преобразован в pro c позже.

1 Ответ

3 голосов
/ 05 мая 2020

Я понимаю вашу озабоченность по поводу инъекции SQL. Насколько мне известно, имена таблиц / столбцов / последовательностей нельзя указывать с помощью переменных привязки. Однако вы можете выполнить простую проверку перед выполнением небезопасного кода:

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"
...