Oracle의 select 문을 쉘 변수에 할당하는 방법

Oracle의 select 문을 쉘 변수에 할당하는 방법

잘 작동하는 스크립트가 있습니다 TOAD.

SELECT max (ID)+1 from apps_details;

쉘 스크립트에서 실행하려고 하면 다음 오류가 발생합니다.

DB_CONNECT="XXXXX/XXXXX@XXXXXX"

echo "Inserting the DataBase"
/oravl01/oracle/12.1.0.1/bin/sqlplus -s $DB_CONNECT <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048

ID_VAL=`SELECT max (ID)+1 from apps_details;`
exit
END
/pciuser/tools/jenkins/jenkins/scripts/Jenkins_Internal/Create_Jenkins_Container/InsertToDB.ksh[31]: syntax error at line 1: `(' unexpected

31호선행을 참조 하지만 일단 작업을 oravl01삭제하면 작동했기 때문에 문제가 존재하지 않는다는 것을 알고 있습니다 .ID_VAL

올바른 구문은 무엇입니까?

답변1

이 명령은 나에게 효과적이었습니다.

DB_CONNECT="XXXXX/XXXXX@XXXXX"

ID_VAL=$(sqlplus -s $DB_CONNECT <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048
SELECT max (ID)+1 from apps_details;
exit;
END
)

echo $ID_VAL

답변2

내 생각에는 먼저 명령을 정의한 다음 실행하여 출력을 저장하는 것이 더 깔끔하고 간단할 것 같습니다.

DB_CONNECT="XXXXX/XXXXX@XXXXXX"

read -r -d '' command <<END
set head off
set feedback off
set pagesize 2400
set linesize 2048
SELECT max (ID)+1 from apps_details;
exit
END

echo "Inserting the DataBase"
ID_VAL=$(/oravl01/oracle/12.1.0.1/bin/sqlplus -s "$DB_CONNECT" <<<"$command")

이렇게 하면 출력을 변수에 쉽게 저장하고 명령을 스크립트 흐름에서 분리할 수 있으므로 나중에 이해하고 유지 관리하기가 더 쉬워집니다.

답변3

대략 다음과 같은 몇 가지 대안이 있습니다.테든의 답변, SQL*Plus의 출력을 더 쉽게 처리하려고 합니다.당신은 노력하고 있습니다쉘 변수로 가져옵니다 ID_VAL.

기본적으로 SQL*Plus에서 실행되는 SQL 문은 해당 데이터 유형에 따라 너비가 달라지는 열로 구성된 형식화된 보고서를 생성합니다. 이로 인해 잠재적으로 원치 않는 효과가 발생할 수 있습니다. 예를 들어 지적한 왼쪽 패딩 숫자댓글에서.

데모:

$ DB_CONNECT="user/password@db"
$ ID_VAL="$(sqlplus -s $DB_CONNECT <<'END'
set feedback off
set head off
set pagesize 0
SELECT 123 FROM DUAL
/
END
)"
$ printf '"%s"\n' "$ID_VAL"
"       123"
$ printf '%s' "$ID_VAL" | od -An -tx1
 20 20 20 20 20 20 20 31 32 33

몇 가지 대안:

  1. 숫자를 선택하면 문자열로 변환하고 SQL 문에서 잘라냅니다. 위 스크립트의 다른 모든 내용은 동일하게 유지됩니다( SELECT테스트 목적으로 계속해서 더미 명령문을 사용하겠습니다).

    SELECT TRIM(TO_CHAR(123)) FROM DUAL;
    
  2. dbms_output.put_linePL/SQL 블록에 사용됩니다.

    ID_VAL="$(sqlplus -s $DB_CONNECT <<'END'
    set serveroutput on
    set feedback off
    DECLARE
    myvar NUMBER;
    BEGIN
    SELECT 123 INTO myvar FROM DUAL;
    dbms_output.put_line(myvar);
    END;
    /
    END
    )"
    

    이는 set serveroutput on필수입니다. 그렇지 않으면 출력이 표시되지 않습니다.

(1)과 (2)를 결합하면 다음과 같은 결과를 얻습니다.

$ printf '"%s"\n' "$ID_VAL"
"123"
$ printf '%s' "$ID_VAL" | od -An -tx1
 31 32 33

그러나 유지하려는 공백 문자가 있는 문자열(예 foo: )을 선택하면 이러한 방법이 실패합니다. 문자열을 따옴표로 묶고 제거하거나 다음을 수행할 수 있습니다.

  1. SQL*Plus에서 출력 형식을 CSV로 지정합니다.

    ID_VAL="$(sqlplus -s -M "CSV ON" $DB_CONNECT <<'END'
    set feedback off
    set head off
    SELECT '  foo  ' FROM DUAL;
    END
    )"
    printf '"%s"\n' "$ID_VAL"
    ""  foo  ""
    

    숫자와 달리 문자열은 큰따옴표로 묶여 있으며 약간의 후처리가 필요합니다. 반환된 값에 문자가 포함되어 있지 않다고 가정하면 다음을 사용하여 시작 및 끝 문자(다른 모든 문자는 변경되지 않음)를 제거하는 <newline>방법이 있을 수 있습니다 .sed"

    ID_VAL="$(sqlplus -s -M "CSV ON" $DB_CONNECT <<'END' | sed 's/^"//; s/"$//;'
    

최선의 선택은 실제 사용 사례에 따라 다릅니다.

관련 정보