最近のトラックバック

最近のコメント

2017年1月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
無料ブログはココログ

ORACLE

2011年10月27日 (木)

SQL*Plusとsqlcmd

なんで、sqlcmd(SQL Server Mangement Studioも)、SQL*Plusみたいな表示書式の設定ができないんだろう?なんか理由があったのかなぁ。

SQL*PlusのCOLUMN FORMATとかSET NUMFORMATとかね。

2011年1月 5日 (水)

「メモリ領域外の項目にアクセスしようとしている」エラー(114)

pro*cobolで作成したCOBOLプログラムを実行した際、「メモリ領域外の項目にアクセスしようとしている」というエラーが発生。

error code: 114, pc=0, call=1, seg=0
114 Attempt to access item beyond bounds of memory (Signal 11)

プリコンパイル後のCOBOLソースを使って、試しにステップ実行してみると、"CALL SQLBEX"の箇所でエラーが発生していることを確認。

原因は、プリコンパイルするときのprocob.exeと、 SQLLIB_lib(orasql11.lib)のバージョンが不一致のためだった(10gと11gが混在している環境で、パスの設定がおかしかった)。

なので、ただしく11gに合わせて再度リコンパイル→実行すると、正常終了になった。

2010年8月 2日 (月)

db_file_mutlit_block_read_count

結論は、Oracle 10gR2とそれ以降では、Oracleにお任せにしたほうがよいということで。

Ask Tom "db_file_multiblock_read_count"

DB_FILE_MULTIBLOCK_READ_COUNT

2010年6月17日 (木)

SQLServerのストアドみたいな感じにするには

SQL Serverの場合だと、ストアド内で実行されたSELECTの結果をそのままレコードセットに突っ込まれますが、Oracleの場合だと、そういうわけには行かず、こういうやり方があると昨日初めて知りました。

pipelinedを使うやり方だそうです(まだ試してないですが)。

<a href="http://d.hatena.ne.jp/Sikushima/20100614/1276477218">ストアドプロシージャでできないと思うのはOracleのせい - SQLer 生島勘富 の日記</a>

2009年5月14日 (木)

「SSDだとOracleは速い?」

 これらの結論としてChaffanjon氏は、典型的なオンライントランザクション処理でOracleデータベースを使っている場合、I/O性能がボトルネックになっているケースでは、Seagateの1万RPMのHDD2台を1台のIntel製SSDで置き換えるほうが有利としている。同等のスループットが出せるだけでなく、応答速度が2倍になる。  また、ピーク時のSSDの性能はメモリに迫るものがあり、SSDでは685TPS(応答時間30ms)、メモリでは821TPS(応答時間24ms)となったという。  逆にCPU性能がボトルネックになっている場合、SSDへの置き換えでは、容量単価が高くなるばかりで、HDDを置き換えたときの性能向上が限定的になる、としている。
SSDだとOracleは速い? サンの技術者がベンチ公表 - @IT

2009年4月22日 (水)

重複行の削除(rowidを使ったやり方)

これがその1(極値関数の利用)

DELETE FROM Products P1
WHERE rowid < ( SELECT MAX(P2.rowid)
                   FROM Products P2
                  WHERE P1.name = P2. name
                    AND P1.price = P2.price ) ;

EXISTSを使ったパターン(非等値結合の利用)

DELETE FROM Products P1
WHERE EXISTS ( SELECT * FROM Products P2
                 WHERE P1.name = P2.name
                   AND P1.price = P2.price
                   AND P1.rowid < P2.rowid );

つまりは、重複している行のうち、一番デカイROWID以外のレコードは削除!ってことです

再帰クエリー

かなりウカツだったんですが、いつの間にやらSQLServerでは使えるようになっていたのですな!

[TSQL]再帰クエリ
再帰クエリその2
再帰SQL — Let's Postgres

Oracleでは、共通表式のWITH句は使えますが、WITH RECURSIVEによる再帰SQLはできませんでしたね。
かろうじてCONNECT BYによる階層問い合わせが出来ましたが、件数多いと全然帰ってこなかったんで、今までほとんど遣ったことないです。


2008年11月27日 (木)

動的SQL

Ask Tom "how to dynamically generate cursors with..."

質問した人は、テーブル名をパラメータにして動的にupdate文を生成したいらしい。

やり方は、

CREATE OR REPLACE PROCEDURE populate_email(p_in_table_name VARCHAR2)

AS
   
    TYPE cur_type IS REF CURSOR;
    tmp_cur cur_type;
   
    TYPE email_rec IS RECORD (
        intid internetaddress.intid%TYPE,
        intaddress internetaddress.intaddress%TYPE);   
    query varchar2(100);
   
    tmp_rec email_rec;
BEGIN
   
    query := 'select i.intid, i.intaddress
    from internetaddress i, '||p_in_table_name ||' b
    where i.intid = b.id';
   
    OPEN tmp_cur  FOR query;
    LOOP
        FETCH tmp_cur INTO tmp_rec;
        EXIT WHEN tmp_cur%NOTFOUND;
   
        EXECUTE IMMEDIATE
        'update '||p_in_table_name ||' a
        set a.ademal = substr(trim('||tmp_rec.intaddress||'),1,50)
        where a.id = '||tmp_rec.intid;

    END LOOP;
   
    EXECUTE IMMEDIATE
    'COMMIT';

    CLOSE tmp_cur;

END;

一方Tomの回答は、

execute immediate '
update (select a.ademal, substr( trim( i.intaddress ) ) intaddress
       from ' || dbms_assert.sql_object_name( p_in_table_name ) || ' a,
          internetaddress i
      where i.intid = a.id )
  set ademal = intaddress';



			

2008年6月13日 (金)

行移行と行連鎖

あいまいだったので整理。

連鎖:一行が複数ブロックにまたがって格納されている状態

で、連鎖は以下の2つ、行移行と行連鎖に分かれる。

行移行:
 発生条件:更新によりレコードの長さが拡張し、現在そのレコードが格納されているブロック内に収まる事が出来なくなった場合
 現象:別のブロックにレコードが移行し、元の場所には移行元のROWIDが残される

行連鎖:
 発生条件:1レコードの長さが1ブロックに収まらない場合
  ※なんか項目(列)が多い+項目長が長い、という組み合わせで発生するケースだけど、たとえばブロックサイズを8KBとしたとき、8KB(正確には違いますが)以上の長さのレコードってすごくないですか?TMの佐藤さんが見たらダメダシ間違いなし

2008年6月11日 (水)

行(レコード)を列(カラム)として表示

これも、行(レコード)を列(カラム)として表示するやり方。
ありがとうTom!

Ask Tom "Column to rows"

質問をした人は、こんなふうにUNIONするやり方を紹介。
CREATE TABLE rows_to_column AS
SELECT * FROM (
SELECT field_cnst, field_1 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_2 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_3 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_4 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_5 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_6 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_7 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_8 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_9 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_10 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_11 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_12 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_13 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_14 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_15 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_16 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_17 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_18 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_19 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) UNION ALL
SELECT field_cnst, field_20 FROM table1 t1 WHERE field_cnst IN (SELECT fnm_ln_id FROM table2) ) src

一方Tomの回答は、

scott%ORA10GR2> create or replace view vw
  2  as
  3  select to_char(empno) f1,
  4         ename f2,
  5             to_char(hiredate) f3,
  6             to_char(sal) f4,
  7             to_char(comm) f5,
  8             job f6,
  9             deptno field_cnst
10    from scott.emp;

View created.

scott%ORA10GR2>
scott%ORA10GR2> with data
  2  as
  3  (select level C from dual connect by level <= 6)
  4  select case C when 1 then f1 when 2 then f2 when 3 then f3 when 4 then f4 when 5
then f5 when 6 then f6 end val
  5    from vw, data
  6   where field_cnst in (select deptno from scott.dept)
  7  /

VAL
----------------------------------------
ANALYST

20182.53
09-DEC-82
SCOTT
7788
CLERK

800
17-DEC-80
SMITH
7369
SALESMAN
300
1600
20-FEB-81
ALLEN
7499
SALESMAN
500
....