スポンサーサイト

--年--月--日 【 スポンサー広告


上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

DBMS_ASSERT.SQL_OBJECT_NAME

2010年04月18日 【 001.DBMS_ASSERT


※目次、略語についてはこちらから。

--------------------------------------------------
 SQL_OBJECT_NAME ファンクション
--------------------------------------------------


「SQL_OBJECT_NAME ファンクション」は
指定した文字列と同じオブジェクトが
存在するか検証した上で値をそのまま返す機能を持つ。
検証に失敗するとエラーになる。


select
dbms_assert.SQL_OBJECT_NAME('TEST') RES1
from DUAL;


RES_1
_________________________

TEST


select
dbms_assert.SQL_OBJECT_NAME('TEST_PROC') RES2
from DUAL;


RES_2
_________________________

TEST_PROC



以下はエラーになる。


select
dbms_assert.SQL_OBJECT_NAME('TEST_BK') RES3
from DUAL;


行2でエラーが発生しました。:
ORA-44002: オブジェクト名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行283



判断に大文字小文字の区別は無いようだが
返す値は渡す値と同じ文字規則となるようだ。


select
dbms_assert.SQL_OBJECT_NAME('tEst') RES4
from DUAL;


RES_4
_________________________

tEst

スポンサーサイト

DBMS_ASSERT.SCHEMA_NAME

2010年04月18日 【 001.DBMS_ASSERT


※目次、略語についてはこちらから。

--------------------------------------------------
 SCHEMA_NAME ファンクション
--------------------------------------------------


「SCHEMA_NAME ファンクション」は
指定した文字列と同じスキーマ(Oracle的には「ユーザー」かな)が
データベース上に存在するか検証した上で値をそのまま返す機能を持つ。
検証に失敗するとエラーになる。


select
dbms_assert.SCHEMA_NAME('SYS') RES1
from DUAL;


RES_1
_________________________

SYS



以下はエラーになる。


select
dbms_assert.SCHEMA_NAME('sys') RES2
from DUAL;

行2でエラーが発生しました。:
ORA-44001: スキーマが無効です
ORA-06512: "SYS.DBMS_ASSERT", 行243



大文字小文字の区別があるようだ。

ちなみにD-QUOTもダメなようだ。
※ダメというより「D-QUOTのついたユーザー名」という解釈なのかもしれない。


select
dbms_assert.SCHEMA_NAME('"SYS"') RES3
from dual;

行2でエラーが発生しました。:
ORA-44001: スキーマが無効です
ORA-06512: "SYS.DBMS_ASSERT", 行243

DBMS_ASSERT.QUALIFIED_SQL_NAME

2010年04月18日 【 001.DBMS_ASSERT


※目次、略語についてはこちらから。

--------------------------------------------------
 ENQUOTE_NAME ファンクション
--------------------------------------------------


※こちらは比較的省略して記述しているので
 「SIMPLE_SQL_NAME ファンクション」を先に読んでおくことを推奨。


「QUALIFIED_SQL_NAME ファンクション」は
渡した文字列が修飾SQL名か検証した上で値をそのまま返す機能を持つ。
検証に失敗するとエラーになる。

修飾SQL名とか更にわかんないんだけど・・・orz orz orz


とりあえずSIMPLE_SQL_NAMEと同様に実験。


select
dbms_assert.QUALIFIED_SQL_NAME('hogehoge') RES_1
from DUAL;


RES_1
_________________________

hogehoge



以下のは「修飾SQL名」と変わっただけで
SIMPLE_SQL_NAMEと同様のエラーとなる。


・dbms_assert.QUALIFIED_SQL_NAME('hoge''hoge') RES_2
・dbms_assert.QUALIFIED_SQL_NAME('1hogehoge') RES_4
・dbms_assert.QUALIFIED_SQL_NAME('(´_`) (´_`)') RES_6

行2でエラーが発生しました。:
ORA-44003: 修飾SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146



次の2つはSIMPLE_SQL_NAMEと異なり、
QUALIFIED_SQL_NAMEでは大丈夫のようだ。


select
dbms_assert.QUALIFIED_SQL_NAME('h@ge') RES_3
from DUAL;

RES_3
_________________________

h@ge


select
dbms_assert.QUALIFIED_SQL_NAME('hoge.hoge2') RES_5
from DUAL;

RES_5
_________________________

hoge.hoge2



SIMPLE_SQL_NAMEで成功したものは
QUALIFIED_SQL_NAMEでもエラーは無く、成功となった。


・dbms_assert.QUALIFIED_SQL_NAME('"hoge''hoge"') RES_7
・dbms_assert.QUALIFIED_SQL_NAME('"h@ge"') RES_8
・dbms_assert.QUALIFIED_SQL_NAME('"1hogehoge"') RES_9
・dbms_assert.QUALIFIED_SQL_NAME('"hoge1.hoge2"') RES_10
・dbms_assert.QUALIFIED_SQL_NAME('"(´_`) (´_`)"') RES_11



さて、違いの現れた2つを見てみよう。

(1)dbms_assert.QUALIFIED_SQL_NAME('h@ge') RES_3
(2)dbms_assert.QUALIFIED_SQL_NAME('hoge.hoge2') RES_5


(1)は実は「テーブル名@データベースリンク名」というチェックを
しているのである。
そして(2)は「テーブル名.列名」というチェックをしているわけだ。


なので例えば以下のようなものもOKである。


select
dbms_assert.QUALIFIED_SQL_NAME('user1.table1.col1@dblink1') RES_12
from DUAL;

RES_12
_________________________

user1.table1.col1@dblink1



「ユーザー名.テーブル名@.列名データベースリンク名」という形式に
則っているからOKなのだ。
SIMPLE_SQL_NAMEは当然エラーとなる。


調べ切れていないので断定はできないけど

SIMPLE_SQL_NAME ⊂ QUALIFIED_SQL_NAME

なのかなぁ・・・

DBMS_ASSERT.SIMPLE_SQL_NAME

2010年04月18日 【 001.DBMS_ASSERT


※目次、略語についてはこちらから。

--------------------------------------------------
 SIMPLE_SQL_NAME ファンクション
--------------------------------------------------


「SIMPLE_SQL_NAME ファンクション」は
渡した文字列が単純SQL名か検証した上で値をそのまま返す機能を持つ。
検証に失敗するとエラーになる。

単純SQL名とか直訳過ぎてわかんないんだけど・・・orz


select
dbms_assert.SIMPLE_SQL_NAME('hogehoge') RES_1
from DUAL;


RES_1
_________________________

hogehoge



このファンクションは
以下のようにいろんなパターンでエラーになる。


select
dbms_assert.SIMPLE_SQL_NAME('hoge''hoge') RES_2
from DUAL;


行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146


select
dbms_assert.SIMPLE_SQL_NAME('h@ge') RES_3
from DUAL;


行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146


select
dbms_assert.SIMPLE_SQL_NAME('1hogehoge') RES_4
from DUAL;


行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146


select
dbms_assert.SIMPLE_SQL_NAME('hoge.hoge2') RES_5
from DUAL;


行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146


select
dbms_assert.SIMPLE_SQL_NAME('(´_`) (´_`)') RES_6
from DUAL;


行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146



逆に以下のようなものはエラーにならなかったりする。


select
dbms_assert.SIMPLE_SQL_NAME('"hoge''hoge"') RES_7
from DUAL;


RES_7
_________________________

"hoge'hoge"


select
dbms_assert.SIMPLE_SQL_NAME('"h@ge"') RES_8
from DUAL;


RES_8
_________________________

"h@ge"


select
dbms_assert.SIMPLE_SQL_NAME('"1hogehoge"') RES_9
from DUAL;


RES_9
_________________________

"1hogehoge"


select
dbms_assert.SIMPLE_SQL_NAME('"hoge1.hoge2"') RES_10
from DUAL;


RES_10
_________________________

"hoge1.hoge2"


select
dbms_assert.SIMPLE_SQL_NAME('"(´_`) (´_`)"') RES_11
from DUAL;

※間に半角スペース4つ


RES_11
_________________________

"(´_`) (´_`)"



ぱっと見、わけわからないファンクションだが
「SELECT文で抽出する列名にそのまま指定できるかどうか」が
一番近い表現かもしれない。


例えば以下のようなテーブルから列を指定して抽出する場合、どうなるか。


desc TEST

名前
_________________________

_hoge NUMBER(1)


select
dbms_assert.SIMPLE_SQL_NAME('_hoge') RES_12
from DUAL;

行2でエラーが発生しました。:
ORA-44003: SQL名が無効です
ORA-06512: "SYS.DBMS_ASSERT", 行146


select
dbms_assert.SIMPLE_SQL_NAME('"_hoge"') RES_13
from DUAL;

RES_13
_________________________

"_hoge"


<抽出で列をD-QUOTで括っていない場合>

select _hoge from TEST;

行1でエラーが発生しました。:
ORA-00911: 文字が無効です。



<抽出で列をD-QUOTで括っている場合>


select "_hoge" from TEST;

_hoge
_________________________

5



こういうのをこのファンクションで事前にチェックして
D-QUOTで括っていない場合はエラーにしましょう、
という考えなわけ。


以下のような時に使うのかな。


create or replace procedure TEST_PROC(p_col in varchar2)
is
v_msg varchar2(4000);
v_sql varchar2(500);
begin
v_sql := 'select ' || p_col || ' from TEST';
execute immediate v_sql;
dbms_output.put_line('成功しますた');
exception
when others then
v_msg := sqlerrm;
dbms_output.put_line(v_msg);
end;
/


begin
test_proc('_hoge');
end;
/

ORA-00911: 文字が無効です。


begin
test_proc('"_hoge"');
end;
/

成功しますた

DBMS_ASSERT.NOOP

2010年04月18日 【 001.DBMS_ASSERT


※目次、略語についてはこちらから。

--------------------------------------------------
 NOOP ファンクション
--------------------------------------------------


「NOOP ファンクション」は
渡した文字列をそのまま返す機能を持つ。
このファンクションのみVARCHAR2とCLOBの2択となる。
※CLOBは個人的にあまり経験が無いので記述しないことにする。

 ・FUNCTION NOOP(str IN VARCHAR2) RETURNS VARCHAR2
 ・FUNCTION NOOP(str IN CLOB) RETURNS CLOB


select
dbms_assert.NOOP('hogehoge') RES_1
from DUAL;


RES_1
____________

hogehoge


select
dbms_assert.NOOP('hoge''hoge') RES_2
from DUAL;


RES_2
____________

hoge'hoge


select
dbms_assert.NOOP('hoge"hoge') RES_3
from DUAL;


RES_3
____________

hoge"hoge


select
dbms_assert.NOOP('hoge""hoge') RES_4
from DUAL;


RES_4
____________

hoge""hoge



S-QUOTの場合に
エスケープがあるものの、基本的にはそのまま返している感じ。
使い道が分からない・・・
 
プロフィール

Author:らんばーど





-*-*-*-*-*-*-*-*-*-*-*-*-

広く浅く、内容薄く。
自分のペースで楽しく学ぶ。

あなたに役立つ情報が
奇跡的にここで見つかれば
嬉しいですね。
※拍手歓迎(笑)

-*-*-*-*-*-*-*-*-*-*-*-*-

【64bit環境】
Windows7 Professional
Core i7-3930K C2-Step
16GB RAM

【32bit環境】
WindowsXP Professional
Core2 Duo E8600 3.33GHz
4GB RAM

-*-*-*-*-*-*-*-*-*-*-*-*-

【音楽の目指すポジション】

自分の気持ちを
素直に表現できる、
そんな音楽が
作れるようになりたい 

-*-*-*-*-*-*-*-*-*-*-*-*-

記述内容の正確性、
および動作保障等に関して
一切責任をもちません。

カテゴリ
ブログ内検索
最新記事
リンク
月別アーカイブ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。