잘 작동하는 스크립트가 있습니다 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
몇 가지 대안:
숫자를 선택하면 문자열로 변환하고 SQL 문에서 잘라냅니다. 위 스크립트의 다른 모든 내용은 동일하게 유지됩니다(
SELECT
테스트 목적으로 계속해서 더미 명령문을 사용하겠습니다).SELECT TRIM(TO_CHAR(123)) FROM DUAL;
dbms_output.put_line
PL/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
: )을 선택하면 이러한 방법이 실패합니다. 문자열을 따옴표로 묶고 제거하거나 다음을 수행할 수 있습니다.
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/"$//;'
최선의 선택은 실제 사용 사례에 따라 다릅니다.