忙しい現代人の腰&肩のお悩み対策!

こんにちは、いつもお世話になっております。
現在、会社で動的SQLを使用してとある開発をおこなっているのですが、
どうしても上手くいかないので、どなたか教えて下さいm(__)m
下記の動的SQL文で最後から2行目のSQL:DBMS_OUTPUT.PUT_LINE(varDel);
を実行するとORA-06502: PL/SQL:
数値または値のエラー: 文字列バッファが小さすぎます。のエラーが
発生します、過去ログやgoogleで検索をかけてみたのですが、
どうにも解決方法がわからず困っています・・・・
お知恵のある方、教えて下さいませm(__)m
※多分、sql文が長いせいだとは思うのですが、どうしても
これ以上は短くできず、静的ではなく、動的で動かさなければならない
という条件付きなんですが、宜しく御願いします。

DECLARE
numkeepD NUMBER := 0; -- データ保管期間格納用
varAST VARCHAR2(4) := '**'; -- アクセス区分定義外格納用
varkeepD VARCHAR2(2000); -- KEEP_DAYS取得SQL文格納用
varDel VARCHAR2(2000); -- DELETE文格納用

BEGIN
varkeepD := 'SELECT KEEP_DAYS FROM SMCI4T910 WHERE ACC_KBN = '''||varAST||'''';
DBMS_OUTPUT.PUT_LINE(varkeepD);
EXECUTE IMMEDIATE (varkeepD) INTO numkeepD;
DBMS_OUTPUT.PUT_LINE(numkeepD);
-- アクセスログデータ削除SQL文格納
varDel := 'DELETE FROM '||cTABLE_STCI1T910||' ST910 '
||'WHERE '
||'ST910.DELETE_FLG = SCIS_CTS.cDEL_NO AND '
||'EXISTS('
||'SELECT 1 '
||'FROM SMCI4T910 SM910 '
||'WHERE '
||'ST910.ACC_KBN = SM910.ACC_KBN AND '
||'ST910.ACC_CYMD < TO_CHAR(SYSDATE - SM910.KEEP_DAYS,''YYYYMMDD'') AND '
||'ST910.ACC_KBN <> varAST AND '
||'SM910.DELETE_FLG = SCIS_CTS.cDEL_NO)';
DBMS_OUTPUT.PUT_LINE(varDel);
--EXECUTE IMMEDIATE (varDel)
END;

このQ&Aに関連する最新のQ&A

A 回答 (3件)

ごめんなさい、"SUBSTRB"の方がいいですね。



文字数ではなくバイトで切り出しです。
    • good
    • 0
この回答へのお礼

すみません、お蔭様で無事に解決できましたm(__)m本当に、ありがとうございます。また、返信が遅れて申し訳ありませんでした・・・・・

お礼日時:2007/08/03 20:47

DBMS_OUTPUTでエラーになるような気がしないんですが・・


DBMS_OUTPUTの部分をコメントにすると、エラーが無くなるんですかね?

ちなみに、組み立てている動的SQL文が間違っているので、もう一度確認された方が良いですよ。
動的SQLをEXECUTEしたところでエラーになるはずです。
    • good
    • 0
この回答へのお礼

返信と御指摘ありがとうございますm(__)m、確かにSQL文が間違っていました・・・・ちなみになんですが、私が調べた範囲内ではDBMS_OUTPUTを使用する際に255バイト(?文字?と言った方がいいのでしょうか)以上の際にエラーが出ました・・・間違っていたらすみません・・
完成したものは下記のような感じになりました。
varDel := 'DELETE FROM '||cTABLE_STCI1T910||' ST910 '
||'WHERE '
||'EXISTS('
||'SELECT 1 '
||'FROM '||cTABLE_SMCI4T910||' SM910 '
||'WHERE '
||'SM910.KEEP_DAYS > 0 AND '
||'ST910.ACC_KBN = SM910.ACC_KBN AND '
||'ST910.ACC_CYMD < TO_CHAR(SYSDATE - SM910.KEEP_DAYS,''YYYYMMDD'') AND '
||'ST910.ACC_KBN <> '''||varAst||''' AND '
||'SM910.DELETE_FLG = '''||SCIS_CTS.cDEL_NO||''')';

※御回答いただいた方、本当にありがとうございました。

お礼日時:2007/08/03 20:52

SUBSTRを使って、2~3回に分けてOUTPUTしてみてはどうでしょう。

    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QORA-06502のエラー

以下のPL/SQLを実行すると、ORA-06502:数値または値のエラーとでます。途中までは、INSERTできるのですが、IF文の180個目くらいでエラーになります。そのあたりをCur1の宣言時にWhereで指定するとうまくいきます。

DECLARE

CURSOR Cur1 IS
SELECT MOJI
FROM A_TBL
;

CNT NUMBER(10);
KAKKO_FL NUMBER(1);

BEGIN

CNT := 0;
KAKKO_FL :=0;

FOR Cur_Rec1 IN Cur1 LOOP

FOR S IN 1 .. LENGTH(Cur_Rec1.MOJI) LOOP

IF(ASCII(SUBSTR(Cur_Rec1.MOJI,S,1)) = 33129) THEN /*33129は'('*/

EXECUTE IMMEDIATE ' INSERT INTO EDD.test1116
VALUES( ''' || Cur_Rec1.MOJI || ''' ) ';

END IF;

END LOOP;

END LOOP;

END;

なにがなんだか、さっぱりわからないので、どうか、ご教授ください。

以下のPL/SQLを実行すると、ORA-06502:数値または値のエラーとでます。途中までは、INSERTできるのですが、IF文の180個目くらいでエラーになります。そのあたりをCur1の宣言時にWhereで指定するとうまくいきます。

DECLARE

CURSOR Cur1 IS
SELECT MOJI
FROM A_TBL
;

CNT NUMBER(10);
KAKKO_FL NUMBER(1);

BEGIN

CNT := 0;
KAKKO_FL :=0;

FOR Cur_Rec1 IN Cur1 LOOP

FOR S IN 1 .. LENGTH(Cur_Rec1.MOJI) LOOP

IF(ASCII(SUBSTR(Cur_Rec1.MOJI,S,1)) = 33129) THEN...続きを読む

Aベストアンサー

もしや Cur_Rec1.MOJIが NULLになることはありませんか?

Cur_Rec1.MOJI が NULLですと、それを引数にする
ほぼすべての関数が NULLを返しますから、現在のコードではおかしな動きになります。

各所に NVL関数を使ってみてください。

QStatement ignored というエラー

Oracle 9iを使ってsqlファイルを実行させたところ、タイトルにあるように、
PL/SQL: SQL Statement ignored
というエラーメッセージが出力されました。
いろいろ検索してみると、これは、私にシステム権限がないことからおこるとあったのですが、
その設定変更の仕方がいまいちよくわかりませんでした。設定変更のしかたを教えていただけないでしょうか。
また、設定変更したことによって変わるのは私自身のシステム権限だけであって、他にコンピュータ(UNIX)を共有している人たちには影響はありませんよね?
立て続けに質問ばかりすみませんが、よろしくおねがいします。

Aベストアンサー

PL/SQLで権限がないということは、EXECUTE PROCEDUREシステム権限がないということでしょうか・・・。
前後のエラーも記載していただいた方が良いとは思いますが。

システム権限の付与方法は下記で行うことが可能です。
※ここでいう"ユーザ"はOracleユーザのことでスキーマとイコールです。
1.SYSTEMまたはSYS(DBA権限を持ったユーザ)でログイン
2.grant execute procedure to [対象ユーザ];
  または
  grant resource to [対象ユーザ];

以上で一応権限付与はできますが、どのような処理を行いたいかによって、これだけで解決するかどうかわかりません。
また、他の人への影響ですが、ユーザをどのように使用しているか、どのようなポリシーのシステムかによって異なります。(「私自身」というのが、セッションのことかスキーマのことかわかりませんでした。)
同じユーザを他の人と共通で使っていれば、もちろん他の人へ影響が出ますし、一人1ユーザ(スキーマ)で割当てられていれば、影響なく使えます。
「影響が出る」という意味は、セキュリティレベルが権限付与された分落ちるということで、機能的に使用できなくなることはありません。

なお、セッション単位で権限を割当てる方法はないと思っています。
付与した権限をセッション終了次第revokeすれば、元に戻るのではないでしょうか。

PL/SQLで権限がないということは、EXECUTE PROCEDUREシステム権限がないということでしょうか・・・。
前後のエラーも記載していただいた方が良いとは思いますが。

システム権限の付与方法は下記で行うことが可能です。
※ここでいう"ユーザ"はOracleユーザのことでスキーマとイコールです。
1.SYSTEMまたはSYS(DBA権限を持ったユーザ)でログイン
2.grant execute procedure to [対象ユーザ];
  または
  grant resource to [対象ユーザ];

以上で一応権限付与はできますが、どのような処理を...続きを読む

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QPL/SQLでログを確認したい。

以下のPL/SQLで取ってきた値をログか何かで確認したいのですが、いい方法がありますか?
想像では5行目あたりにログはきだす記述をするのかなと思うのですが、方法がわかりません。
どなたか教えてください。

--------------------------------------------
1select count(*) into vn_CNT from t_ukerui
2where no_toi = :new.no_toi
3 and no_uke = :new.no_kyaku
4 and no_gyo = 1;
5
6if ( vn_CNT > 0 ) then
7
--------------------------------------------

Aベストアンサー

参考URLをみていただければ分かりますが。
例えば、サーバのDドライブのtempフォルダにtest.txtというログファイルを出力するのであれば。
--------------------------------------------------
OUT_FILE UTL_FILE.FILE_TYPE;

BEGIN
OUT_FILE := UTL_FILE.FOPEN('d:\temp', 'test.txt','A');
EXCEPTION
WHEN OTHERS THEN
OUT_FILE := UTL_FILE.FOPEN('d:\temp', 'test.txt','W');
END;
UTL_FILE.PUT_LINE(OUT_FILE,'(vn_CNT = ' || vn_CNT || ')');
UTL_FILE.FCLOSE(OUT_FILE);
--------------------------------------------------
こんな感じでしょうか。
ログファイルがあれば追加、なければ新規で作成、件数のメッセージを一行書いて、最後にクローズしています。
これを実行すると、

(vn_CNT = 1)
(vn_CNT = 5)
(vn_CNT = 0)

のように出力されます。

参考URL:http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/sq_pl07_1.htm

参考URLをみていただければ分かりますが。
例えば、サーバのDドライブのtempフォルダにtest.txtというログファイルを出力するのであれば。
--------------------------------------------------
OUT_FILE UTL_FILE.FILE_TYPE;

BEGIN
OUT_FILE := UTL_FILE.FOPEN('d:\temp', 'test.txt','A');
EXCEPTION
WHEN OTHERS THEN
OUT_FILE := UTL_FILE.FOPEN('d:\temp', 'test.txt','W');
END;
UTL_FILE.PUT_LINE(OUT_FILE,'(vn_CNT = ' || vn_CNT || ')');
UTL_FIL...続きを読む

QPL/SQLのコンパイルエラーについて(ignored)

以下はPL/SQLの一部です。

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO,
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;


実行すると以下のエラーがでます。。
行番号 = 27 列番号 = 3 エラー・テキスト = PL/SQL: SQL Statement ignored
行番号 = 30 列番号 = 5 エラー・テキスト = PL/SQL: ORA-01747: user.table.column、table.columnまたは列指定が無効です

ちなみにOEMコンソールで作成しています。
M_SEATというテーブルは存在します。

権限どうのと言われているのはわかるのですが結局なにが原因なのかわかりません。
どなたか教えてください。

以下はPL/SQLの一部です。

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO,
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;


実行すると以下のエラーがでます。。
行番号 = 27 列番号 = 3 エラー・テキスト = PL/SQL: SQL Statement ignored
行番号 = 30 列番号 = 5 エラー・テキスト = PL/SQL: ORA-01747: user.table.column、table.columnまたは列指定が無効です...続きを読む

Aベストアンサー

if (vn_CNT > 0 ) then
-- 座席マスタ更新実行
行27 update M_SEAT
行28 set M_SEAT.CD_PC = :new.NK_PC ,
行29 M_SEAT.CD_TANTO = :new.CD_TANTO
行30 where M_SEAT.NO_PORT = :new.NO_PORT ;
end if ;

これでどうでしょうか?

NK_PCというカラムはありますか?

QSQL、2つのテーブルで条件一致したものだけdeleteする方法は?

オラクルSQLで質問です

やりたいことは、
テーブルAから以下の条件に該当するデータを削除する。
基本的にはテーブルBの内容と比較して、一致したもの。

条件(全ての条件を満たすこと)
 テーブルA.AAA = テーブルB.AAA
 テーブルA.BBB = テーブルB.BBB
 テーブルB.CCC > 0


調べたところ、SQLサーバでは以下のように
from を2つ書いて実現できるようです。
が、今回はオラクルなので文法エラーになります。

delete FROM テーブルA FROM テーブルB
where
テーブルA.AAA = テーブルB.AAA
AND
テーブルA.BBB = テーブルB.BBB
AND
テーブルA.CCC > 0
;
commit;


よろしくお願いします

Aベストアンサー

delete 文の細かい構文はちょっと覚えてませんが
サブクエリ使えばいいんじゃないですか

delete from table_a
where 主キーカラム = (
select table_a.主キーカラム
from table_a, table_b
where
指定の条件
)

QOracleでの文字列連結サイズの上限

Oracle9iでテーブル内容をスプール出力していますが、カラム単位で余白を削除したい
(トリムをかけたい)ので以下のようにカラムを連結させてスプールしています。
set colsep ','
spool test.csv
select
a ||','||
b ||','||
c
from test_table
spool off

実際の項目数は100以上あり、レコードの最大長も数千バイトになりますが、
各項目にMAXの値を入力して上記スプールを実行したところ、以下のエラーメッセージが
出力されました。
「ORA-01489: 文字列を連結した結果、長さが最大長を超えました」

データを連結した結果の長さが上限を超えたということなのでしょうが、
この最大長はどこで設定されているものなのでしょうか?
また、そもそもスプール出力でトリムが効かないためにこのようなやり方で
出力していますが、他によい方法をご存知の方いましたら教えて下さい。
よろしくお願いします。

Aベストアンサー

>>Code Tipsの内容も実際に試してみたのですが、結局のところ項目を連結させる
>>やり方では4000バイトまでが限度ということだと判断したのですが

4000バイトまでが限度 とは、どのような理由からでしょうか?
以下のSQLで4000バイトオーバーは可能です。(32KBの壁はあります)

既に完成度の高いスクリプトがデバッグ済みで存在するのに
同じものを 1からコーディングするのは、(自分の勉強にはなるとは思いますが) 意味のない行為だと思いますので、
Code Tipsをお勧めしました。

SPOOL HOGE.TXT
SET PAGESIZE 0
SET LINESIZE 32767
SET LONG 40000
SET LONGC 40000
SET TRIMSPOOL ON
SET FEEDBACK OFF
SET VERIFY OFF

SELECT
TO_CLOB('')
|| LPAD('1', 4000,'1')
|| LPAD('2', 4000,'2')
|| LPAD('3', 4000,'3')
|| LPAD('4', 4000,'4')
|| LPAD('5', 4000,'5')
|| LPAD('6', 4000,'6')
|| LPAD('7', 4000,'7')
|| LPAD('8', 4000,'8')
|| LPAD('9', 4000,'9')
|| LPAD('0', 4000,'0')
FROM DUAL
/
SPOOL OFF

>>Code Tipsの内容も実際に試してみたのですが、結局のところ項目を連結させる
>>やり方では4000バイトまでが限度ということだと判断したのですが

4000バイトまでが限度 とは、どのような理由からでしょうか?
以下のSQLで4000バイトオーバーは可能です。(32KBの壁はあります)

既に完成度の高いスクリプトがデバッグ済みで存在するのに
同じものを 1からコーディングするのは、(自分の勉強にはなるとは思いますが) 意味のない行為だと思いますので、
Code Tipsをお勧めしました。

SPOOL HOGE.TXT
SET...続きを読む

Qbatファイルからsql文実行

クライアントOS:WIN2000
Oracle:9i(サーバ(UNIX)上にあります)

現在、クライアントからbatを起動し、SQL文を投げ、結果を取得したいと思っております。
(SQL文は単純にTBLをカウントしているだけです)

・batの中身
sqlplus %UID%/%PASS%@%SID% @test.sql > output

結果は取得出来るのですが、余分な情報も結果に出力されてしまいます。結果のみを出力させるにはどうすればよろしいでしょうか?

・余分な情報
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.4.0 - Production
に接続されました。

Aベストアンサー

sqlplus に -S オプションを追加してみればどうでしょうか。

参考URL:http://biz.rivus.jp/sqlplus_overview.html

Q3つの表の外部結合

表A、B、Cの3つがあり、Aのすべての行を出力したいと考えています。
外部結合を用いるのだとは思うのですが、3つの表に対して行う場合の
書き方がわからず困っています。
ご教授いただけないでしょうか?
select * from a,b,c
where a.商品ID =b.商品ID (+) and b.商品ID (+) =c.商品ID (+)
としてみましたが、うまくいきませんでした。

Aベストアンサー

ansi構文の趣旨からいえば、結合条件と絞り込み条件は分けて書くので・・

select *
from a
left join b on (a.商品ID =b.商品ID)
left join c on (b.商品ID =c.商品ID)
where a.年月 = 任意の値

と書くのが一般的でしょうね。

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング