• 締切済み

sqlplusで引数渡しを行い、sql内でさらにその引数の一部の使用法

sqlplusで引数渡しを行い、sql内でさらにその引数の一部の使用法 Oracle:10.2.0.1.0 Windows:XP 例えば sqlplus test/test @hoge.sql 2010 10M にて実行しますが(年・月の意味の引数をわたしています) hoge.sqlのCD1_xの数値1が引数の一部10を取得できるようにSQLに埋め込みたいと考えています。年と月で抽出するパターンが12カ月分ありまして、このCSV作成時に10Mというデータも埋め込みが必要なため、引数を単純に10にはしたくはないのです。 良い方法がありましたらお教えして頂きたくどうぞ宜しくお願いいたします。 <TESTテーブルのレイアウト> CD1_1~CD1_6、CD2_1~CD2_6、・・・CD12_1~CD12_6の12カ月分の項目があります。 <バッチファイルにて引数を指定し実行する> sqlplus test/test @hoge.sql %1 %2 <呼び出すhoge.sqlの内容> spool c:\test\data_&1&2.csv select PRODUCT_ID||','|| '&1'||','|| '&2'||','|| CD1_1||','|| <-- ここはCD1_1ではなくてCDx_1的な。xは引数の一部にしたいのです。 CD1_2||','|| CD1_3||','|| CD1_4||','|| CD1_5||','|| CD1_6 from TEST; spool off exit

  • Oracle
  • 回答数3
  • ありがとう数13

みんなの回答

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.3

提示した例は引数を元にSQL文を作成して、作成したSQL文を実行しています。 あなたは、引数を直接展開して項目名にしようとしてませんか? SUBSTRを使うには一度SQL文として実行する必要があるので、実行したいSQL文を生成するSQL文を実行しています。 引数がそのまま展開されるなら&1で直接書けるのですけど。例えば SELECT &1 FROM &2 に引数A10とTABなら SELECT A10 FROM TAB で実行できますが、 SELECT SUBSTR('&1',1,1) FROM &2 は SELECT SUBSTR('A10',1,1) FROM TAB にしかなりません。SUBSTR('A',1,1)を SELECT A FROM TAB にしたいなら、 SELECT 'SELECT '||SUBSTR('&1',1,1)||' FROM '||&2 FROM DUAL を実行すると SELECT A FROM TAB になるので、これを実行するとお望みのSQL文ができると思います。

hanahana1234
質問者

お礼

SaKaKashi様 懇切丁寧に教えて下さり、 貴重なお時間を頂戴してしまいすみません。 本当にどうもありがとうございました。 上記の方法で実行したいと思います。 サンプルをいくつも提示頂きまして勉強になりました。 非常に感謝しております。 本当にどうもありがとうございました!

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.2

項目名を引数の一部で生成するって事ですか? それをするには、SELECT文を文字列として作成して、spoolに書き込んで、 その書き込んだspoolを実行することです。 Unixでの例を提示します。これは指定の表の項目名をuser_tablesから参照して、 select文を生成してspoolに書いて、最後にできあがったspoolを実行してます。 参考にしてみてください。 #!/usr/bin/ksh # DBOWNER=gx DBPASS=gx DBSV= SQLDIR=${HOME}/tmp CSVDIR=${HOME}/tmp SQLDIR=. CSVDIR=. # if [ $# = 0 ] then echo usage : db2csv table-name [ condition ] exit 9 fi tabfrom=$1 if [ $# -ge 2 ] then tabwhere="where $2" else tabwhere="" fi # echo "db2csv from ${tabfrom} by ${tabwhere}" # sql1=${SQLDIR}/desc${tabfrom}.sql sql2=${CSVDIR}/csv${tabfrom}.csv sqlplus -s ${DBOWNER}/${DBPASS}${DBSV} <<EOT SET TRIMSPOOL ON set pages 0 set hea off set termout off set feedback off set echo off set showmode off set verify off set trimspool on spool ${sql1} select 'SET HEA OFF' from dual; select 'SET PAGES 0' from dual; select 'SET TERMOUT OFF' from dual; select 'SET TRIMSPOOL ON' from dual; select 'SET FEEDBACK OFF' from dual; select 'SET LINES 4096' from dual; select 'SPOOL ${sql2}' from dual; select 'ALTER SESSION SET NLS_DATE_FORMAT=''YYYYMMDDHH24MISS'';' from dual; select 'SELECT '''||chr(34)||'''||' from dual; select column_name||'||' from user_tab_columns where table_name = upper('${tabfrom}') AND COLUMN_ID = 1 ; select ''''||chr(34)||','||chr(34)||'''||'|| column_name||'||' from user_tab_columns where table_name = upper('${tabfrom}') AND COLUMN_ID > 1 order by COLUMN_ID; select ''''||chr(34)||'''' from dual; select 'FROM ${tabfrom} ${tabwhere}' from dual; select '/' from dual; EOT ### sqlplus -s ${DBOWNER}/${DBPASS}${DBSV} <<EOT @${sql1} EOT ###

hanahana1234
質問者

お礼

sakakashiさん サンプルまで頂いてしまい、すみません。 どうもありがとうございました。 最初のアドバイスにて以下のように記述すると、惜しいところまで行くのですが concatした部分が文字列になってしまいまして編集した項目名がそのまま文字列になってcsvにはかれてしまいました。 concat(concat('CD',substr('&2',1,2)),'_1') のこの部分を何とか変数名として認識させる方法はご存じでしょうか。 度々の質問とても恐縮なのですがアドバイス頂けたら幸いです。 宜しくお願いいたします。 <変数名が文字列と認識されてしまうSQL> select PRODUCT_ID||','|| '&1'||','|| '&2'||','|| concat(concat('CD',substr('&2',1,2)),'_1')||','|| concat(concat('CD',substr('&2',1,2)),'_2')||','|| concat(concat('CD',substr('&2',1,2)),'_3')||','|| concat(concat('CD',substr('&2',1,2)),'_4')||','|| concat(concat('CD',substr('&2',1,2)),'_5')||','|| concat(concat('CD',substr('&2',1,2)),'_6') from TEST; spool off exit

  • SaKaKashi
  • ベストアンサー率24% (755/3136)
回答No.1

SUBSTR('&1',3,2)

hanahana1234
質問者

お礼

早速ご回答ありがとうございます。 CDx_1等の項目にx部分へSUBSTRを連結し埋め込むにはどうやればよいのでしょうか。 度々の質問になりすみません。 宜しくお願いいたします。

関連するQ&A

  • crontabで登録したシェルが動かなくなってしまいました

    シェル初心者です。 宜しくお願い致します。 bashコマンドで起動させると上手く動くのですが、 crontabコマンドで登録すると、全く動いてくれないのです。 ネットで色々調べましたが、原因がさっぱりわかりません。 何卒ご教示お願い致します。 【シェルの内容】 ●オラクルに接続し、hoge.sqlにかかれているsql文を実行するシェルです。 cd /h/ho/hog/hoge/ sqlplus hoge/hoge2@hogehoge @/h/ho/hog/hoge/hoge.sql ちなみにhoge.sqlは、以下のような内容です。 (⇒test.sqlの内容をcsvファイルに出力する) set echo off set heading off set pause off set pagesize 0 set linesize 32767 set feedback off set trimspool on set termout off column log_date new_value log_date_text noprint select to_char(sysdate,'yyyymmddhh24miss') log_date from dual; spool TEST_&log_date_text..csv @/h/ho/hog/hoge/test.sql ※test.sqlはselect文です。 spool off exit 納期が近づいているため、かなり焦っています。 宜しくお願い致します。 ●その他 サーバ:Sun OS 5.9 oracle:9.2.0.1.0                          以上

  • SQL初心者です。

    SQL初心者です。 SQLPlusをコマンドプロンプトで実行していたのですが、定型のSQL文のためバッチファイルにてスケジュール実行したいと考えています。 コマンドプロンプトを開いて実行していたときはspoolした内容に実行sqlも出力されていたのですが、バッチファイルで同じようにspoolすると実行sqlは出力されず結果のみになってしまいます。 実行したsqlも出力させるには特別にsetするものがあったりするのでしょうか? echoのon、offは試しましたが結果は同じでした。 方法をご教示いただけたら助かります。 よろしくお願いします。

  • SQL*LoaderのDATA引数

    Shellからsqlldrコマンドを実行する際に複数のロードファイル名を引数として渡したい。 しかし、コマンドラインから実行する際にデータ引数は複数指定できないと言われます。 ということは、制御ファイル内のINFILEに複数ファイル名を指定しないといけないと思うのですが、 ロードファイル名は固定ではなく、複数の場合もあれば1つの場合もあります。 詳しく説明させていただきますと、Shellで他のFTPサーバーから取得したCSVのフルパスをすべて取得しそれを制御ファイルのINFILEに渡したいのです。 なにか良い方法はありますでしょうか? ご存知の方がいればご教示いただきく存じます。 よろしくお願いいたします。

  • DBからタブ区切りのCSVデータを抽出する

    DBからCSVにしてデータを取り出そうと、ネットで検索して みようみまねでやってみました。(下記の場合カンマ区切りですが) タブ区切りで整列したデータを抽出したいのですが、特に、 (4)のように隣合う項目の間がかなり離れていて見えにくい状態で CSVファイルが作成されてしまいます。 (1)のように整列した形で、タブ区切りのCSVデータを抽出するには、 どのようにしたら宜しいのでしょうか? (2)、(3)は、試してみた実行ファイルです。 環境は、oracle10g windowsXPです。 (1)目的の結果の表示------------------------------- 653-5689 ZM05 田中太郎 YOKOHAMAS 4 4  9 097005・・・・・ 以下試してみたbatファイルとsqlで抽出 (2)batファイル---------------------------------- sqlplus ABCD/ABCD@oracle.host1.ser @abc.sql (3)sqlファイル----------------------------------- set echo off set heading off set termout off set pause off set pagesize 0 set trimspool on set feedback off set colsep "," set term off spool hoge.txt select * from T_JUTYU; spool off exit (4)結果--------------------------------- 653-5689 ,ZM05 田中太郎 ,YOKOHAMASI 4, 4, , ,9 ,097005 , 1 ,18 , , , , , 0 ,asahi asahi ,08-12-23,08-12-23, ------------------------------------------------まで結果

  • プロシージャの戻り値を取得する方法

    perlからSQLPLUS->プロシージャを実行してその戻り値を取得。 戻り値が0なら次の処理へ、0以外ならエラー処理へというようなことをやりたいと思っています。 perlの実行コマンドは以下。 $sqlcmd = "sqlplus$DBUSER$PASS\@DB_ALIAS\@$SQLFILE $OUTFILE"; $sql_ret = system("$sqlcmd") >>8; この$sql_retにプロシージャの戻り値が入るようにしたいのです。 プロシージャを実行する$SQLFILEは以下のようなSQLです。 --------------------------------------------------- set serveroutput on WHENEVER SQLERROR EXIT 1 spool &1; DECLARE RetVal NUMBER; BEGIN RetVal := 実行ストアドファンクション; END; / spool off; EXIT SQL.SQLCODE; ---------------------------------------------- エラーが起きたときにファンクションは1を返すようにしているのですが、 それがSQLPLUSの実行結果の戻り値に反映されません。 どうしたらいいのでしょうか? よろしくお願いします。

  • 複数のsqlファイルを実行するスクリプト

    シェルスクリプトで特定のディレクトリ配下にあるsqlファイルを実行したいのですが、 どのようにすればいいのでしょうか? 今まではsqlファイルが決まっていた為、明示的にファイルを指定出来たのですが、ファイル名が固定でなくなった 為、悩んでいます。 以前は以下のような形で行っていました。 ----------------------------------------- #!/bin/sh #sqlplusでDB接続 sqlplus /nolog <<EOF conn USER (パスワード入力) #ユーザ確認 show user #sql実行 @/home/hoge/sql_01 @/home/hoge/sql_02 @/home/hoge/sql_03 commit; exit EOF ---------------------------------- ここでsql実行したいファイルの特定のディレクトリ配下にある全てのsqlファイル にして実行するようにしたいです。 もし、分かる方いれば教えてください。 よろしくお願いします。

  • [SQL Server] コマンドプロンプトからのCSV形式出力

    SQL ServerのテーブルデータをSELECTしてダブルコーテ区切りのCSVに出力したいと考えております。 ・batファイルからの起動を希望。 ・出力CSVファイル名はbatファイルより引数で指定したい。 ・出力後、DELETEも行いたい。 OracleだとSQL*Plus環境で下記のようにテキストレベルで簡単にできます。 SQL Serverでも同様のことができないでしょうか? 要は下記をSQL Server版でやりたいということです。 参考:Oracleだと・・・ 同一dirに、abc.batとabc.sqlを用意しabc.batを実行すると20070601.csvが生成される。 1.abc.bat rem ----abc.bat-ここから---- sqlplus usr/pwd@host @abc.sql 20070601.csv rem ----abc.bat-ここまで---- 2.abc.sql ----ファイル名=abc.sql-ここから--- set echo off set heading off SET VERIFY OFF set FEEDBACK OFF set TRIMSPOOL on set termout off set pagesize 0 set linesize 32767 spool &1 select '"'|| カラム1 ||'",'|| '"'|| カラム2 ||'",'|| '"'|| カラム3 ||'"' from テーブル1; spool off delete from テーブル1; exit ----ファイル名=abc.sql-ここまで--- 20070601.csv結果 -ファイル名=20070601.csv-ここから--- "20060726","scott","356160" "20060727","tiger","463391" "20060728","manager","1930" -ファイル名=20070601.csv-ここまで--- DBサーバ環境 OS:Win2003SvrR2 SQL Serverバージョン:わかりません。(2003にのってるので最近のだと思われます) Oracle経験者でSQLServer初心者です。マニュアルもなく、Web検索しても「SQL」「Server」ってなかなかうまくひっかからない!! ので質問あげさせていただきます。

  • SQL実行結果の出力を見やすくしたい

    Oracle 10gを使用して勉強をしています。 SQL実行結果の出力が見にくくて困っています。 以下、(1)は自分が実行したSQL文ですが、(2)のように見やすく出力したいです。 どのようにすればよいのでしょうか? また参考となるWEB URLがある場合、頂けたら嬉です。 (1)自分が実行したSQL文 SQL> select 2 sid,serial#,username,osuser,program,machine,terminal 3 from v$session 4 where type = 'USER'; SID SERIAL# USERNAME ---------- ---------- ------------------------------ OSUSER PROGRAM ------------------------------ ------------------------------------------------ MACHINE ---------------------------------------------------------------- TERMINAL ------------------------------ 543 39 SYS oracleuser sqlplus@HOGE-net (TNS V1-V3) HOGE-net pts/1 SID SERIAL# USERNAME ---------- ---------- ------------------------------ OSUSER PROGRAM ------------------------------ ------------------------------------------------ MACHINE ---------------------------------------------------------------- TERMINAL ------------------------------ 544 5 SYS oracleuser sqlplus@HOGE-net (TNS V1-V3) HOGE-net pts/0 (2)こんな感じで出力させたいです。 select sid,serial#,username,osuser,program,machine,terminal from v$session where type = 'USER'; SID SERIAL# USERNAME OSUSER PROGRAM  MACHINE   TERMINAL ---- ------- --------- ------ ---------- ---------  -------- 139     2      TEST Owner sqlplus.exe   HOGE_XP HOGE_XP 144     20    SYSTEM      ORACLE.EXE HOGE_XP  HOGE_XP

  • バッチからのSQLPLUS実行について

    はじめまして。 SQLPLUSでご質問ををさせてください。 環境 OS:Win2003server Oracle:10g バッチから、以下のようにSQLを実行したいと考えています。 バッチファイル sqlplus ID/PASS@インスタンス名 @SQLファイル.sql SQLファイル.sql set trimsool on set pagesize 0 set linsize 2000 set feedback off set colsep ',' spool on spool ABC.txt select * from xxx; spool off exit; ご質問  バッチファイルからSQLファイル.sqlが呼ばれているのですが、  接続時にENTERキーを押下しないと、後続の処理が実行されません。  ENTERキー押下後のメッセージ内容が  「バージョン情報の表示や、接続されました。」と出力されているため、  接続時の処理と思われます。    上記でENTERキーを押下せずに、処理を実行させるためにはどうすればよろしいでしょうか。  初歩的な質問で申し訳ありませんが、宜しくお願い致します。

  • 動的にSPOOLファイルのファイル名を生成したい

    実行するSQLは同じだが、実行するタイミングによってSPOOLファイルのファイル名を変更したい。 たしかdefineコマンドでできた記憶があるがうまくいかない。 そもそもコマンドが間違っているような気もします。 ご教授ください。 sqlplus user/user @file SPOOLファイル名 @file ----------------------------------------------- set difine SPOOL_FILE = &1 SELECT .... FROM .... spool SPOOL_FILE / sppol off 文字列開始 "SPOOL_FILE..."は長すぎます。最大サイズは1文字です。 SP2-0332:スプールファイルが作成できません。