web-dev-qa-db-ja.com

Oracleにはテーブル列のビットデータ型がありません

Oracleは、true/falseシナリオのbitデータ型またはその他のタイプをサポートしていません。文化固有の問題に関係なく、特定の文字を使用して「はい」/「真」を表すことにより、代わりにchar(1)フィールドを使用しますか?

代わりにcharの代わりにNumber(1,0)にする必要があります-代わりに0はfalse/noと見なされ、それ以外はtrue/yesと解釈されますか?

これは実行可能ですか?


Oracleが単純なブール型をサポートしないのはなぜですか?

26
Martin Milan

Number(1)よりもchar(1)を選択します。これは、文字を適切に選択することで、どの文字がどのブール意味を持つかが明確になるためです。

もちろん、さまざまなバリエーションすべてに対抗し、1つを選択して、列にチェック制約を設定することで、それを確実に使用する必要があります。

おそらくあなたの場合は遅くなるでしょうが、別のツールからスキーマを生成することで、少なくとも一貫性の問題に対処することがよくあります。私は個人的にはこの目的のために休止状態を好みますが、それは状況によって異なります。

そしてもちろん、それは明白な怠慢です。さらに悪いことに、PL/SQLにはブール値がありますが、SQL文では使用できません。

11
Jens Schauder

CHAR(1)、および「1」と「0」のみを許可する制約を使用します。

...

col CHAR(1),
CONSTRAINT cons_atable_col1 CHECK (col1 IN ('1','0'))
27
Samuel

私は英語を母国語としないため、1と0または「1」と「0」のどちらかを使用する傾向があります。英語でコーディングしていない場合は、「Y」と「N」を使用しても意味がありません(そうです、母国語のコーディングが存在します)。 「SI」と「NO」または「S」と「N」を使用しても、アクセント付きの文字で変数に名前を付けるのと同じようには見えません。逆に、1と0は、C、PHPまたはJavaScriptでコーディングした場合、かなり標準的です。いずれの場合も、他の文字を許可しないように常に適切な制約を追加します。主観的な問題ですが、CHARまたはNUMBERを選択してもパフォーマンスはそれほど向上しないと思います。引用符を付ける必要がないため、数値の方が好きです:)

私はそれが明白な省略であることに同意しますが、私はいくつかのOracleフォーラムでこの件に関する真剣に白熱した議論を読みました。それは一種の宗教的な問題です。ブール値はアプリケーションデータ型に属し、データベースコアには場所がないと主張する人もいます。正直なところ、それは私たちが長い間それがないと私たちが意図的なものであったと言ったほうがいいものの1つだと思います。

ちなみに、MySQLにはBOOLEAN型がありますが、これはTINYINT(1)の同義語であるため、最終的には1および0になります。これは、1および0に評価される定数TRUEおよびFALSEも持っているため、問題ありません。

16

これが、このトピックに関する Ask Tom ディスカッションです。この問題についてOracle中心の見解を示します。

ストレージに関しては、char(1)は実際には少し(しゃれが意図されていない)より効率的です。

SQL> CREATE TABLE xx (c CHAR(1), n NUMBER);

Table created

SQL> insert into xx values('T', 1);

1 row inserted

SQL> select dump(c), dump(n) from xx;

DUMP(C)             DUMP(N)
------------------- -------------
Typ=96 Len=1: 84    Typ=2 Len=2: 193,2
9
DCookie

このOracleガイドによると、NUMBER(3)を使用する必要があります。クレイジーですが、本当です。

http://docs.Oracle.com/cd/B19306_01/gateways.102/b14270/apa.htm

3
GilesDMiddleton

Number(1)はchar(1)と同じです。特に、既存のchar(1)に追加される場合。それは混乱を増すだけです。

FWIW、内部ビュー(USER_TAB_COLUMNSなど)のOracleはvarchar2(3)(YESおよびNO)を使用します。ただし、ここで100%一貫しているかどうかはわかりません。

2
Thilo

Oracleは、さまざまなデータディクショナリビューで内部的に「ビット」(データ型自体ではない)を使用します。

たとえば、dba_usersビューには次のものが含まれます。

..
        , DECODE (BITAND (u.spare1, 128), 128, 'YES', 'NO')
..
        , DECODE (BITAND (u.spare1, 256), 256, 'Y', 'N')
..

これはある方法でこれを回避する方法を示しています。 「ブール」ビットを頻繁に変更する必要がない場合は、(少なくとも)Oracle 6以降のOracleと同じアプローチを採用できます。 NUMBER列を持つテーブルを作成し、その上にBITAND操作の複雑さを隠すビューを作成します。

ps。余談ですが、Oracle JDBCは「ビット」データ型 https://docs.Oracle.com/cd/E16338_01/appdev.112/e13995/Oracle/jdbc/OracleTypes.html#BIT としてPL/SQLにはブール値があることはすでにご存じでしょう。それはおそらくあなたを助けませんが。それがあなたのケースに適している場合は、上記のBITANDアプローチを参照してください。

0
Tagar

質問は古いですが、Oracleの最新リリースが使用されるまで、それはまだ有効な質問です。

私はこの方法で問題を解決します:true/falseに可能な値とローカライズされた表示テキストを保持するテーブルを作成します。 T $ KEYWORDS ITEMNO ITEMTEXT ITEMTEXT_DE ITEMTEXT_FE ... 0 False Falsch 1 True Wahr

True/Falseの代わりに、これを選択、非選択などにすることもできます。

次に、このテーブルの列に前向きキーを追加します。これにより、有効な値のみが存在し、ローカリゼーションによって変更されることはありません。

別の良い解決策は、データ列にチェック制約を使用することです。クライアントのローカリゼーションに応じて、同じデータベース/列で値が異なる可能性がある場合、このofcは機能しません。

alter table tblLocations add flag number CONSTRAINT <constraintname> CHECK (flag IN (1,0));

0
SomeCoder