2017-03-23 3 views
0

다음 PL/SQL을 작성하여 동적으로 주어진 공식을 문자열로 실행합니다. 수식의 최종 출력은 o_ 변수에 반환 될 것으로 기대했던 19을 반환해야합니다.동적 PL/SQL 블록을 실행하여 합계를 실행하고 값을 반환하십시오.

실제로 코드는 오류없이 실행되지만 예상 한 결과를 제공하지 않습니다. DBMS_SQL 패키지를 올바르게 사용하고 있습니까?

이 문제를 복잡하게 만드는 요인은 입력 문자열 (또는 수식)에 몇 개의 바인드 변수가 포함되는지 알 수 없다는 점입니다. 따라서 EXECUTE IMMEDIATE은 바인딩이 필요한 변수의 수를 미리 알고 있기 때문에 EXECUTE IMMEDIATE 동적 PL/SQL 실행 전략을 사용할 수 없습니다.

올바른 방법으로 문제에 접근하고 있습니까? 이 작업을 수행하는 더 좋은 방법이 있습니까?

DECLARE 
    cur_ INTEGER; 
    r_ NUMBER; 
    str_ VARCHAR2(2000) := 'BEGIN :out := :x * 3 + :y; END;'; 
    x_ NUMBER := 3; 
    y_ NUMBER := 10; 
    o_ NUMBER; 
BEGIN 
    cur_ := Dbms_SQL.open_cursor; 
    Dbms_SQL.Parse (cur_, str_, Dbms_SQL.Native); 
    Dbms_SQL.Bind_Variable (cur_, ':out', o_); 
    Dbms_SQL.Bind_Variable (cur_, ':x', x_); 
    Dbms_SQL.Bind_Variable (cur_, ':y', y_); 
    r_ := Dbms_SQL.Execute (cur_); 
    Dbms_SQL.Close_Cursor (cur_); 
    Dbms_Output.Put_Line ('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_); 
END; 
+0

문자열이 고정 된 문자열입니까? 그렇지 않다면 [이 질문] (http://stackoverflow.com/questions/5209981/use-of-bind-variable)의 답변에있는 것과 같은 것을 사용할 수 있습니다. – Nitish

+0

@Nitish 당신이 뭘 말하고 있는지 잘 모르겠습니다. 나는 그 페이지에서 내가 묻고있는 질문에 가까울만한 것을 찾을 수 없다. – cartbeforehorse

답변

3

전화가 DBMS_SQL.VARIABLE_VALUE에 누락되었습니다.

DECLARE 
    cur_ INTEGER; 
    r_ NUMBER; 
    str_ VARCHAR2(2000) := 'BEGIN :out := :x * 3 + :y; END;'; 
    x_ NUMBER := 3; 
    y_ NUMBER := 10; 
    o_ NUMBER; 
BEGIN 
    cur_ := DBMS_SQL.OPEN_CURSOR; 
    DBMS_SQL.PARSE (cur_, str_, DBMS_SQL.NATIVE); 
    DBMS_SQL.BIND_VARIABLE (cur_, ':out', o_); 
    DBMS_SQL.BIND_VARIABLE (cur_, ':x', x_); 
    DBMS_SQL.BIND_VARIABLE (cur_, ':y', y_); 
    r_ := DBMS_SQL.EXECUTE (cur_); 
    DBMS_SQL.VARIABLE_VALUE(cur_, ':out', o_); 
    DBMS_SQL.CLOSE_CURSOR (cur_); 
    DBMS_OUTPUT.PUT_LINE ('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_); 
END; 

Your variables: 3, 10, and out: 19, and R: 1 
1

"이중에서 계산 [선택]"을 사용하여 시도해보십시오. 결과 행을 가져 와서 열 값을 가져옵니다.

declare 
    res number; 
    cur_ integer; 
    r_ number; 
    str_ varchar2(2000) := 'select :x * 3 + :y from dual'; 
    x_ number := 3; 
    y_ number := 10; 
    o_ number; 
begin 
    cur_ := dbms_sql.open_cursor; 
    dbms_sql.parse(cur_, str_, dbms_sql.native); 
    dbms_sql.bind_variable(cur_, ':x', x_); 
    dbms_sql.bind_variable(cur_, ':y', y_); 
    dbms_sql.define_column(cur_, 1, o_); 
    r_ := dbms_sql.execute(cur_); 
    res := dbms_sql.fetch_rows(cur_); -- Fetch only the first row, no loop required 
    dbms_sql.column_value(cur_, 1, o_); 
    dbms_sql.close_cursor(cur_); 
    dbms_output.put_line('Your variables: ' || x_ || ', ' || y_ || ', and out: ' || o_ || ', and R: ' || r_); 
end; 
+1

'dbms_sql.execute()'와'dbms_sql.fetch_rows' 대신에'dbms_sql.EXECUTE_AND_FETCH()' –

+0

을 사용하면 매일 뭔가를 배울 수 있습니다. – Rene

+0

@Rene 나는 잠을 자기 전에이 질문을 올렸고, 잠에서 깨어 났을 때도이 솔루션을 생각했다. (나는 코드를 꿈꿔 왔음에 틀림 없다). 실제로 작동합니다 (물론 사용자의 입력 문자열을 수정해야하는 번거 로움). 그러나 Wernfried의 솔루션 양식이 질문에보다 직접적으로 대답하기 때문에이 솔루션을 "수락 된 응답"으로 표시하지는 않을 것 같습니다. 그러나 박스 밖에서 조금 생각하면 +1. 당신의 아이디어는 많이 감사합니다. – cartbeforehorse