Access 2003 SQL Switch はデータ型を破壊しますか?
-
20-09-2019 - |
質問
Access2003を実行しています。Switch を使用して、ブール基準に基づいて日付フィールドを選択しています。
Switch(<criterion>, Date1, 1, Date2)
つまり、「criterion」が true の場合は Date1 を返し、それ以外の場合は Date2 を返します。
Date1 と Date2 は、テーブル内の日付/時刻型の列です。
問題は、Switch がそれらを日付/時刻ではなくテキストとして返すことです。
強制的に伊達っぽさを持たせる方法はないでしょうか?私は試した
Switch(<criterion>, #Date1#, 1, #Date2#)
そして
Switch(<criterion>, Val(Date1), 1, Val(Date2))
どちらも何らかのエラー メッセージが表示されて失敗します。
何か案は?
解決
Immediate If [IIf()] 関数は、あなたがやろうとしていることによりよく一致すると思います。
IIf(<criterion>, Date1, Date2)
ただし、Switch() 関数はデータ型を壊すべきではなく、日付/時刻データ型と互換性がありません。次の関数を考えてみましょう。
Public Function trySwitch(ByVal pWhichDay As String) As Variant
Dim varOut As Variant
varOut = Switch(pWhichDay = "yesterday", Date - 1, _
pWhichDay = "today", Date, _
pWhichDay = "tomorrow", Date + 1)
trySwitch = varOut
End Function
trySwitch("今日") 戻り値 10/6/2009 そして TypeName(trySwitch("今日")) 戻り値 日付
他のヒント
あなたの例で奇妙な何かがあります。
スイッチは、発現ペアを受け入れ、第が真評価された場合、そのペアの値が返され、そうでなければ、それは第二へ渡し、その引数を評価します。
あなたはそれがファレスではないですが、あなたが持つほうが良いと思いますので、それはある、1のように真の治療ているように見えます:
Switch(<criterion>, Date1, True, Date2)
しかし、それは即時If関数の機能のほんの複製だ、式IIf()、およびIIFは、()少ない引数を取ります。
しかし、それはバリアントを返すという点では、同じ問題を抱えています。しかし、あなたは日付としてフォーマットすることができるデータ型にそれを強制することができる必要があります。
しかし、そのバリアントが暗黙的に強要されたり、明示的に行う必要がありますかどうか、あなたがそれを使用している場所によって異なります。列を日付型に強制されますので、クエリの結果では、あなたは、日付として式IIf([基準]、日付1、日付2)からの出力をソートすることができます。
あなたが明示的に強制を行う必要がある場合は、、CDate関数は、()を使用する機能です - あなたはバリアント出力が明示的であることを確信するために、CDate関数()関数でバリアント出力を生成外部の機能をラップしたいです日付タイプに強制ます:
CDate(IIf(<criterion>, Date1, Date2))
しかし、私は完全に別のトラックにオフのように見えるように私は非常によく、ここで重要な何かが欠落している可能性があります...
あなたが問題を再現するためにいくつかのコードとデータを投稿することができ、してください?これはSQLコードにSWITCH()
されるよう、私はSQL DDL(CREATE TABLE
など)、およびDML(データを追加するINSERT INTO
)が最も適切であると思う:)
[気むずかしポイント:AccessデータベースのSQLは、「ブール」データ・タイプを持っていません。これはYESNO
値とすることができるNULL
データタイプを有します。 3値論理はブール値ではありません。
ここではいくつかのSQL DML( ANSI-92クエリモードの構文は次のとおりです)私にとっては予想通り、それがどのように動作するかを実証します。
SELECT TYPENAME
(
SWITCH
(
NULL, #2009-01-01 00:00:00#,
FALSE, #2009-06-15 12:00:00#,
TRUE, #2009-12-31 23:59:59#
)
);
「基準」のいずれかの値を変更し、値が常に型DATETIME
のすなわち「日」として返されます。
UPDATE:
これ
TYPENAME
機能は素晴らしいです ツール...アクセスが解釈しているようです 結果セットの全体の「列」 異なっ
確かに。カラムは、一つだけのデータ・タイプとすることができるので、行におけるTYPENAME()
の結果は誤解を招くことができます。混合型の列値は、より高いデータ型に「昇格」しなければなりません。 Accessデータベースエンジンでは普通であるとして、あなたはそれを吸うと、例えば参照する必要がありますので、プロセスが完全に不透明で、対象のドキュメントが完全に欠如
SELECT #2009-01-01 00:00:00# AS row_value,
TYPENAME(#2009-01-01 00:00:00#) AS row_type
FROM Customers
UNION ALL
SELECT 0.5,
TYPENAME(0.5) AS row_type
FROM Customers
を返す「日付」と「小数」はそれぞれが、列は何になりますか?どうやら、答えは次のとおりです。
SELECT DT1.row_value, TYPENAME(DT1.row_value) AS column_type
FROM (
SELECT DISTINCT #2009-01-01 00:00:00# AS row_value
FROM Customers
UNION ALL
SELECT DISTINCT 0.5
FROM Customers
) AS DT1;
'文字列'?!
...もちろんさえAccessデータベースエンジンのSQLデータ・タイプではありませんています。だから、TYPENAME()
は、うるさく、「ベストフィット」VBAタイプの名前を使用しています。たとえばます:
SELECT TYPENAME(CBOOL(0));
上述したように、を返す「ブール」もかかわらず、何のBooleanデータ型は、AccessデータベースエンジンSQLではありません。そして、
SELECT TYPENAME(my_binary_col)
'文字列' を返します。例えば、同じVBAマッピング制限はCAST
機能(さらに別の迷惑)に適用されますそこには「BINARY
するキャスト」関数はありませんし、CDEC()
機能は、Jet 4.0のため、壊れたまま:(