代码之家  ›  专栏  ›  技术社区  ›  mph

Access 2003 SQL开关是否中断数据类型?

  •  0
  • mph  · 技术社区  · 15 年前

    我正在运行Access 2003。我使用开关根据布尔条件选择日期字段:

    Switch(<criterion>, Date1, 1, Date2)
    

    即,如果“条件”为真,则返回日期1,否则返回日期2。

    日期1和日期2是表中的日期/时间类型列。

    问题是,switch将它们作为文本返回——而不是日期/时间!

    有没有办法强迫他们去约会?我试过

    Switch(<criterion>, #Date1#, 1, #Date2#)
    

    Switch(<criterion>, Val(Date1), 1, Val(Date2))
    

    这两种方法都失败,并出现一条或另一条错误消息。

    有什么想法吗?

    3 回复  |  直到 15 年前
        1
  •  2
  •   HansUp    15 年前

    我认为immediate if[i if()]函数更适合于您正在尝试的操作:

    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 类型名(Tryswitch(“Today”)) 收益率 日期

        2
  •  1
  •   David-W-Fenton    15 年前

    你的例子有点奇怪。

    switch接受表达式对,如果第一个表达式对的计算结果为true,则返回其成对值,否则,它将传递给第二个表达式对,并计算该参数。

    你似乎认为1是正确的,这是因为它不是错误的,但你最好:

      Switch(<criterion>, Date1, True, Date2)
    

    但这只是immediate if函数、iif()和iif()功能的复制,只需要更少的参数。

    但它也有同样的问题,因为它返回一个变量。但您应该能够将其强制为可以格式化为日期的数据类型。

    但是,这个变量是否会被隐式地强制执行,或者您需要显式地执行它,取决于您使用它的位置。在查询结果中,您可以将IIF([条件],日期1,日期2)的输出排序为日期,因为列被强制为日期类型。

    如果必须显式执行强制,则cdate()是要使用的函数--您将用cdate()函数包装生成变量输出的外部函数,以确保变量输出显式强制为日期类型:

      CDate(IIf(<criterion>, Date1, Date2))
    

    但我很可能错过了一些重要的事情,因为我似乎走上了一条完全不同的道路…

        3
  •  1
  •   onedaywhen    15 年前

    你能发布一些代码和数据来重现这个问题吗?因为这是 SWITCH() 在SQL代码中,我认为SQL DDL( CREATE TABLE 等)和DML(DML) INSERT INTO 添加数据)将是最合适的:)

    [选择点:Access数据库SQL没有“Boolean”数据类型。它有一个 YESNO 数据类型,可以是 NULL 值;三值逻辑不是布尔值。]

    这是一些SQL DML( ANSI-92 Query Mode 语法)演示它如何按预期工作:

    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
    

    分别返回“日期”和“小数”,但该列将是什么?显然,答案是:

    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数据类型。所以 类型() 令人恼火的是,它使用了“最适合”的VBA类型的名称。例如:

    SELECT TYPENAME(CBOOL(0));
    

    返回“boolean”,尽管如上所述,Access数据库引擎SQL中没有布尔数据类型。和

    SELECT TYPENAME(my_binary_col)
    

    返回“string”。注:同样的VBA映射限制适用于 CAST 功能(还有另一个烦恼),例如没有“强制转换到” BINARY '函数和 CDEC() 由于Jet 4.0,功能仍然中断:(