2009-06-08 1 views
11

私は最近、私が列挙したいと思っていた、実際に醜いストアドプロシージャを書きました。TSQLの列挙型をシミュレートしますか?

例:

CREATE PROCEDURE Proc_search_with_enum @user int, @account_category {enum} 

私は、SQL 2000のコーディング規約は、あなたが列挙型をシミュレートするか、そうでない場合は、同じ問題に対処するために使うのですかファーストクラスの言語構造として列挙型を、持っていないことを理解できますか?

私はVARCHARとIF @ account_category = 'cat1'を使用するだけですか?

EDIT:T-SQLとC#はクライアント言語です。

編集:ありがとうございます!良いアドバイスの多くは、私は誰もが答え

  • 概要がintを使用してC#の列挙にリーン上方制御投票してきました、私はいくつかの答えを受け入れることができることを望みます。良い C#クライアントコードの場合、TSQLクライアント のコードを読みにくくします。

  • Char/Varcharを使用します。 C#クライアントコード (ローカリゼーションには適していません)のために悪いです。 TSQLコードを読みやすくしています。 パラメータを制限、またはパラメータが表に を挿入しようとしている 場合 テーブル列または外部キーに制約を使用するようにコードをチェック
  • 使用パラメータ。
+0

この質問をご覧ください:http://stackoverflow.com/questions/681828/sqlserver-how-to-bind-fixed-values-to-column/681847 – LukeH

答えて

10

this questionの回答をご覧ください。私の知る限り、列挙型はSQL Serverの一部ではありません。

いずれにしても、列挙型には整数型(INT,、...)の型を使用する方がよいでしょう。通常、選択したプログラミング言語の列挙型は、文字列よりも整数に適しています。 C#ので

は、デフォルトですべての列挙型の値は、あなたも、それらの間にキャストすることができます0から始まる整数に相当し、これは有効なコードです:

public enum MyEnum 
{ 
    FirstEnumValue, 
    SecondEnumValue 
} 

... 

// Assuming you have opened a SqlDataReader. 
MyEnum enumValue = (MyEnum) reader["account_category"]; 

そしてLINQtoSQLもこれをサポートしています。列挙型のプロパティがあり、データベース列が整数型の場合、変換は自動的に行われます。

PostgreSQLで
+3

このテクニックを使用すると、おそらく将来の更新が誤ってC#コードとデータベース値との間の相関関係を壊さないように、列挙型の基礎となる値を明示的に指定することをお勧めします。例:public enum MyEnum {FirstEnumValue = 1、SecondEnumValue = 2}など – LukeH

+0

合意していますが、通常はデフォルト値を使用して最後に新しい値を追加しますが、明示的にするのは良い考えです。 –

2

私は付属の制約とVARCHARのを使用して...私は、彼らが十分説明的でないため、列挙型をシミュレートする数値型を使用して好きではない

CREATE TABLE movie_clip (  
    type VARCHAR(40) NULL CHECK(type IN ('trailer', 'commercial')), 
); 

#=> insert into movie_clip (type) values ('trailer'); 
INSERT 0 1 
#=> insert into movie_clip (type) values ('invalid value'); 
ERROR: new row for relation "movie_clip" violates check constraint "movie_clip_type_check" 

#=> \d movie_clip 
.... 
"movie_clip_type_check" CHECK (type::text = ANY (ARRAY['trailer'::character varying, 'commercial'::character varying]::text[])) 

。上記のスキーマを使って、私は受け取った可能な値をすぐに見ることができますし、すぐにそれらの値の意味も知ることができます。私はその列に無効な値を挿入することができないので、型安全性も取得します。

Postgresのための制約の詳細については

、こちらを参照してください。 http://www.postgresql.org/docs/8.1/static/ddl-constraints.html

+0

PostGreSQLはhttp://www.postgresql.org/docs/9.3/static/datatype-enum.htmlをサポートしています。 PgAdminでそれらを表示するには、あなたの設定でそれらを有効にする必要があります。 –

1

時々、CHAR型はINTよりも使用可能である - 固定サイズの文字はずっと保管室を取らないと、あなたはに「列挙」の値を直接見ることができますデータベースフィールド。コード側との違いはありませんが、SQLツールで直接作業している間は大きな進歩です。

2

一般的には、@ value_category_codeパラメータを呼び出して、少数の列挙値がある場合はCHAR(3)にすることをお勧めします。これらはすべて3文字できれいに表現できます。次に、ドメインは検査制約で強制されます。いくつかの値(4または5以上)がある場合は、通常、@account_category_type_idと呼ばれるtinyint/smallintに切り替え、参照するドメインテーブルを持っています。私たちの組織には厳しいルールはありませんが、これはうまく機能しています。

1

enumにCHAR型を使用する際には細心の注意を払い、app/dbを国際化するには、まったく使用しないでください。
DATAをプレゼンテーションと混同しないでください。言葉が示唆するように、列挙型(エナメーション)は数字です。説明はまったく異なるビジネスです。これを簡潔にするために、列挙型にCHAR変数/フィールドを使用すると、記述のために特定の言語に縛られます。例えば、国際化については忘れることができます。 "Weltmeisterschaft"という言葉がどのような言葉で意味されているのか想像できますか?また、それを間違って書く方法はいくつありますか? 実際には、(小さな)intは、実際には自動記述的ではない値の欠点を実際に持っています。私はそれが完璧な解決策ではないと言いました!

+2

IMHO enumの "code"(account_category_code)は決してローカライズされてはなりません。これは、c#/ C++ enumを定義したアプリケーションソースコードのローカライズに似ています。代わりに、account_category_type_desc(われわれの命名法では)人間が表示する列挙型の記述である必要があります。これは、ローカライズするものです。 – ahains

+0

1)エンドユーザにソースコードを公開させることはできません(しかし、enumのさまざまな翻訳を簡単に定義することができます)2) エンドユーザにコードを使用させると、あなたの言語を知らず、たとえ知っていても、それを意図的に使用したくないかもしれません:dbにアクセスできる人は、手動で値を挿入することができます。3)説明の代わりにコードを使用すると、状況はさらに悪くなります。「WMS」とは、int(文字通り)のどの言語が当てはまるかを推測する必要があります。 –

+0

4)不正な値を挿入する人々(または外部ファイル - あなたのコントロールから外部のソースにも留意してください)のリスクを冒します:これは簡単に避けることができます。 proc/functionです。私はそれが完璧な解決策ではないことに同意しますが、異なる文化や言語の人々と仕事をしている私の経験(18年)で、テーブルや列挙型のCHARキーを使用することで、それは私のアドバイスですが、私はあなたのコード/ dbsをリファクタリングしてあなたのオフィスに来ることはないと思っています:) –

1

SQLでは、アイテムをテーブルに入れて列挙します。アカウントカテゴリのルックアップテーブルを作成し、このパラメータに新しいテーブルの主キーを受け入れるようにします。

2

Enumをシミュレートするビューを作成できます。この記事を参照してくださいhttp://www.olegsych.com/2008/07/t4-template-for-generating-sql-view-from-csharp-enumeration/

+0

このリンクは廃止されました。回答にはリンクの関連情報とリンクが含まれていなければなりません – Aphillippe

+0

このページはまだあります:https://web.archive.org/web/20160728054915/http://www.olegsych.com:80/ 2008/07/t4-template-for-generation-sql-view-from-csharp-enumeration / – Justin

0

これを行う最も簡単な方法は、CHECK制約です。あなたはそれについてhereまたはhereを読むことができます。この制約は、PostgreSQLとOracleでも利用できます。

0

CASE statementを使用できます。

は、あなたがこのような何かを行うことができ、結果セットから列挙風の例を作成するには、次の

SELECT 
    FirstName, 
    LastName, 
    CASE JobTitle WHEN 0 THEN 'Software Developer' WHEN 1 THEN 'Software Architect' WHEN 2 THEN 'President' ELSE 'Staff' END AS 'Job Title', 
    Salary 
FROM 
    Employees 

あなたは基本的にSWITCH文のようなものを通じて整数を実行します。ストアドプロシージャに入れて、同じコードを何度も何度も書く必要はありません。お役に立てれば。 enter code here

関連する問題