Sql “布尔”数据类型。它有一个YESNO数据类型,可以是NULL值;三值逻辑不是布尔逻辑。]

Sql “布尔”数据类型。它有一个YESNO数据类型,可以是NULL值;三值逻辑不是布尔逻辑。],sql,ms-access,ms-access-2003,Sql,Ms Access,Ms Access 2003,下面是一些SQL DML(语法)来演示它是如何按照我的预期工作的: SELECT TYPENAME ( SWITCH ( NULL, #2009-01-01 00:00:00#, FALSE, #2009-06-15 12:00:00#, TRUE, #2009-12-31 23:59:59# ) ); 更改任何“标准”值,该

下面是一些SQL DML(语法)来演示它是如何按照我的预期工作的:

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


更新:

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
分别返回'Date'和'Decimal',但列是什么?显然,答案是:

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)

返回“String”。注:相同的VBA映射限制适用于
CAST
函数(另一个麻烦),例如,没有“CAST to
BINARY
”函数,并且
CDEC()
函数自Jet 4.0以来一直处于中断状态:(

TYPENAME函数是一个很好的工具--+1以及有用的故障排除提示。它告诉我我的值是'Date'和'Null'(对于空条目,很明显),在IIf表达式和开关表达式中,每行的类型结果是相同的。但是Access似乎解释了整个“列”结果集的类型不同:IIf的日期(可临时排序,右对齐),Switch的其他类型(仅限词法排序,左对齐)。这是因为当True和False部分都是Date类型时,IIf()将返回值强制为子类型Date()的变量。Switch()不这样做——它只返回一个变量(可能是字符串的子类型),并且必须用CDate()显式强制执行。@David W.Fenton:记住,我们讨论的是Access数据库SQL中使用的表达式,它没有变量或字符串数据类型,不管TYPENAME()是什么可能会告诉你。TYPENAME函数是一个很好的工具--+1以及有用的故障排除提示。它告诉我我的值是'Date'和'Null'(对于空条目,很明显),在IIf表达式和开关表达式中,每行的类型结果是相同的。但是Access似乎解释了整个“列”结果集的类型不同:IIf的日期(可临时排序,右对齐),Switch的其他类型(仅限词法排序,左对齐)。这是因为当True和False部分都是Date类型时,IIf()将返回值强制为子类型Date()的变量。Switch()不这样做——它只返回一个变量(可能是字符串的子类型),并且必须用CDate()显式强制执行。@David W.Fenton:记住我们讨论的是Access数据库SQL中使用的表达式,它没有变量或字符串数据类型,不管TYPENAME()会告诉你什么。尽管David和onedaywhen的解释很有趣,但IIf还是起了作用(我真的应该一开始就使用它)。有关差异的更多细节,请参阅我对onedaywhen答案的评论,但现在,我只使用IIf。尽管有David和onedaywhen有趣的解释,IIf还是起了作用(我真的应该一开始就使用它)。有关差异的更多详细信息,请参阅我对onedaywhen答案的评论,但现在,我将只使用IIf。有趣的是:当我在交换机内的CDate()中包装Date2时,Access将resultset列视为非日期类型(请参阅我对onedaywhen的评论)。但当我在CDate中包装整个Switch语句时,它将该列视为日期类型(根据相同的排序/单元格对正标准)。例如,“Switch(,Date1,True,CDate(Date2))”的类型不等同于“CDate(Switch(,Date1,True,Date2))。[注意:IIf在这里更好,因为当Date1为Null时它将返回Null,而Switch看到Null Date1并返回一个#Error#,弄脏了结果集]我并不是建议强制传递参数,因为这些参数显然在这一点上具有正确的数据类型。您必须强制到正确的数据类型是Switch()或IIf()的变量输出,正如您所发现的。我将进行编辑以使其更清楚。有趣的是:当我在CDate()中包装Date2时在交换机内部,Access将resultset列视为非日期类型(请参阅我对onedaywhen的注释)。但当我将整个Switch语句包装在CDate中时,它将该列视为日期类型(根据相同的排序/单元格对正标准)。例如,“Switch(,Date1,True,CDate(Date2))”的类型不等同于“CDate(Switch(,Date1,True,Date2))”[注意:IIf在这里更好,因为当Date1为Null时它将返回Null,而Switch看到Null Date1并返回一个#Error#,弄脏了结果集]我并不是建议强制传递参数,因为这些参数显然在这一点上具有正确的数据类型。您必须强制到正确的数据类型是Switch()或IIf()的变量输出,正如您所发现的。我将进行编辑以使其更清楚。
  Switch(<criterion>, Date1, True, Date2)
  CDate(IIf(<criterion>, Date1, Date2))
SELECT TYPENAME
       (
          SWITCH
          (
             NULL, #2009-01-01 00:00:00#, 
             FALSE, #2009-06-15 12:00:00#, 
             TRUE, #2009-12-31 23:59:59#
          )
       );
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;
SELECT TYPENAME(CBOOL(0));
SELECT TYPENAME(my_binary_col)