Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 日期时间';转换失败';使用案例比较时出错_Sql_Sql Server_Datetime_Case_Type Conversion - Fatal编程技术网

Sql 日期时间';转换失败';使用案例比较时出错

Sql 日期时间';转换失败';使用案例比较时出错,sql,sql-server,datetime,case,type-conversion,Sql,Sql Server,Datetime,Case,Type Conversion,我有一个存储字段/值对以进行比较的表,例如: ID FieldName ValueA ValueB ---- ---------- ------- ------ 1 Name ABC XYZ 1 StartDate 2015-05-04 2015-06-05 1 Amount 4 4 2 Name DEF UVW 2

我有一个存储字段/值对以进行比较的表,例如:

ID    FieldName    ValueA      ValueB
----  ----------   -------     ------
1     Name         ABC         XYZ
1     StartDate    2015-05-04  2015-06-05
1     Amount       4           4
2     Name         DEF         UVW
2     StartDate    2015-03-22  2015-02-11
2     Amount       4           4
我试图比较ValueA和ValueB的值,寻找不匹配的值。由于它们在表中存储为varchar(max),有时会出现不应该出现的不匹配,即

ID    FieldName    ValueA      ValueB
----  ----------   -------     ------
3     StartDate    2015-01-30  01/30/2015
因此,我使用
CASE
语句在比较之前转换数据类型,即

Select *
From ComparisonTable
where
(case when FieldName = 'StartDate' then CAST(ValueA as datetime)
      when FieldName = 'Amount' then CAST(ValueA as int)
      else CAST(ValueA as varchar(max))
 end)
=
(case when FieldName = 'StartDate' then CAST(ValueB as datetime)
      when FieldName = 'Amount' then CAST(ValueB as int)
      else CAST(ValueB as varchar(max))
 end)
我犯了一个错误

从字符转换日期和/或时间时转换失败 串

我想这是因为在某个地方,StartDate值输入错误。但是,我进行了以下搜索:

Select *
From ComparisonTable
where FieldName = 'StartDate'
and
(ISDATE(ValueA) = 0
OR
ISDATE(ValueB) = 0)
在我看来,没有任何东西表明所有的日期值都被正确地存储了

我想知道是否有其他人也遇到过类似的问题,或者SQL/SQL Server中是否存在某种固有的东西,不允许在
WHERE/CASE
语句中进行这些类型的数据类型转换

更新 我尝试在一个简单的
选择中使用相同的
案例

SELECT
    (case when FieldName = 'StartDate' then CAST(ValueA as datetime)
          when FieldName = 'Amount' then CAST(ValueA as int)
          else CAST(ValueA as varchar(max))
     end)
    =
    (case when FieldName = 'StartDate' then CAST(ValueB as datetime)
          when FieldName = 'Amount' then CAST(ValueB as int)
          else CAST(ValueB as varchar(max))
     end)
WHERE FieldName IN ('StartDate','Amount')
所有内容都返回为datetime,这意味着即使
int
值也被转换为日期,这让我相信这种类型的
CASE
转换是不允许的。即使
CASE
表示要将“Name”字段转换为
varchar
,它还是将所有内容转换为datetime


如果这是标准的SQL Server行为,是否有任何解决方法可用于进行这些转换?

我知道您试图执行的操作,但不能对这样的单个值使用多个类型。它们都需要是相同的数据类型,才能按照您正在尝试的方式执行

这应该满足您的需要,但这将导致性能不佳,因为没有索引可用于此类比较

Select  *
From    ComparisonTable
Where   
(
    FieldName = 'StartDate'
And Cast(ValueA As DateTime) = Cast(ValueB As DateTime)
)
Or
(
    FieldName = 'Amount'
And Cast(ValueA As Int) = Cast(ValueB As Int)
)
Or
(
    FieldName Not In ('StartDate', 'Amount')
And Cast(ValueA As Varchar (Max)) = Cast(ValueB As Varchar (Max))
)
另一个选项是在数据类型转换后将所有内容转换为
VARCHAR

Select  *
From    ComparisonTable
Where   
(
    case    
        when FieldName = 'StartDate' then CAST(CAST(ValueA as datetime) As Varchar (Max))
        when FieldName = 'Amount' then CAST(CAST(ValueA as int) AS Varchar (Max))
        else CAST(ValueA as varchar(max))
    end
)
=
(
    case 
        when FieldName = 'StartDate' then CAST(CAST(ValueB as datetime) AS Varchar(Max))
        when FieldName = 'Amount' then CAST(CAST(ValueB as int) As Varchar (Max))
        else CAST(ValueB as varchar(max))
    end
)

我提出的一个解决方案是使用
UNION ALL
来分离不同的类型:

SELECT *
FROM ComparisonTable
WHERE FieldName = 'StartDate'
AND CAST(ValueA as datetime) = CAST(ValueB as datetime)
UNION ALL
SELECT *
FROM ComparisonTable
WHERE FieldName = 'Amount'
AND CAST(ValueA as int) = CAST(ValueB as int)
UNION ALL
SELECT *
FROM ComparisonTable
WHERE FieldName = 'Name'
AND CAST(ValueA as varchar(max)) = CAST(ValueB as varchar(max))

它是有效的,但我会将它与其他方法进行效率比较。

嗯。。。将
Amount
转换为
Datetime
似乎有些奇怪。。。因为在你的例子中它的值是4。。。也许你是指整数还是数字?建议:仔细检查“Amount”的预期数据类型,不能在case表达式中混合这样的数据类型。它将遵循数据类型优先规则,并尝试将所有内容转换为日期时间。这是使用EAV的一个挑战部分,但它做得不太正确。在您的查询中,您必须将所有内容转换为字符数据类型才能使其正常工作。@xQbert这是一个复制/粘贴错误。它们正在转换为
int