シェルスクリプト:SQLクエリ出力をファイルにリダイレクトする

シェルスクリプト:SQLクエリ出力をファイルにリダイレクトする

シェルスクリプトで以下のように書きました。

sqlq(){
result=`sqlplus -S sss/eee@sid < $1|grep -v '^$'`
echo $result
}

echo "select * from emp" > q.sql
sqlq q.sql

出力をファイルに送信する必要があります。以下のようにq.sqlでスプールしようとしましたが、成功しませんでした。

echo "SPOOL /tmp/test.txt; select * from emp';SPOOL off" > q.sql

答え1

あなたのコード:

sqlq(){
result=`sqlplus -S sss/eee@sid < $1|grep -v '^$'`
echo $result
}

echo "select * from emp" > q.sql
sqlq q.sql

echo関数の合計変数はsqlq必要ありません。

sqlq () {
  sqlplus -S "sss/eee@sid" < "$1" | grep -v '^$'
}

これは関数の出力を標準出力に送ります(前と同様)。

関数を呼び出すと、その出力をファイルにリダイレクトできます。

cat >query.sql <<END_SQL
SELECT * FROM emp;
END_SQL

sqlq query.sql >result.out

私が使う理由ここのドキュメント利点は、複数行のSQLクエリを非常に簡単に生成できることです。

cat >query.sql <<END_SQL
SELECT data.*
FROM data
  JOIN attributes ON (data.attr_id = attributes.attr_id)
WHERE attributes.name = "Example";
END_SQL

...例えば。

答え2

  1. 関数の出力は、他のコマンドと同様にファイルにリダイレクトできます。例えば
echo "select * from emp" > q.sql
sqlq q.sql > emp.txt
  1. 一時ファイルを必要としないように関数を書き直しましょう。私もそれを省略しgrep -vたり、選択的にする傾向があります。例えば
sqlq() {
  local filter
  filter='cat'

  # very primitive, use getopts for real option handling.
  if [ "$1" == "--delete-blank-lines" ] ; then
    filter='grep -v "^$"'
    shift
  fi

  # each arg is piped into sqlplus as a separate command
  printf "%s\n" "$@" | sqlplus -S sss/eee@sid | $filter
}

sqlq --delete-blank-lines 'select * from emp' > emp.txt

# two sql commands:
sqlq 'select * from emp;' 'select * from foo' > empfoo.txt

# that last example works just as well as:
sqlq 'select * from emp; select * from foo' > empfoo.txt
  1. 多くの改善が可能です。たとえば、この機能の他の便利なオプションは次のとおりです。

    • 使用する代わりに、stdinからsqlコマンドを読み取ると、パイプされていることがprintf検出されます。
    • ファイルからSQLを読み取るオプション
    • sqlplusコマンドに任意のオプションを渡す機能。

関連情報