相关疑难解决方法(0)

转换为datetime仅在WHERE子句上失败?

我遇到了一些SQL服务器查询的问题.事实证明我有一个带有"Attibute_Name"和"Attibute_Value"字段的表,它可以是任何类型,存储在varchar中.(是的,我知道.)

特定属性的所有日期似乎都存储在"YYYY-MM-DD hh:mm:ss"格式中(不是100%确定,这里有数百万条记录),所以我可以毫无问题地执行此代码:

select /*...*/ CONVERT(DATETIME, pa.Attribute_Value)
from 
    ProductAttributes pa
    inner join Attributes a on a.Attribute_ID = pa.Attribute_ID
where 
    a.Attribute_Name = 'SomeDate'
Run Code Online (Sandbox Code Playgroud)

但是,如果我执行以下代码:

select /*...*/ CONVERT(DATETIME, pa.Attribute_Value)
from 
    ProductAttributes pa
    inner join Attributes a on a.Attribute_ID = pa.Attribute_ID
where 
    a.Attribute_Name = 'SomeDate'
    and CONVERT(DATETIME, pa.Attribute_Value) < GETDATE()
Run Code Online (Sandbox Code Playgroud)

我将收到以下错误: 从字符串转换日期和/或时间时转换失败.

怎么会在where子句上失败而不是在select子句上?

另一个线索:

如果不使用Attribute_Name进行过滤,而是使用存储在数据库(PK)中的实际Attribute_ID,它将正常工作.

select /*...*/ CONVERT(DATETIME, pa.Attribute_Value)
from 
    ProductAttributes pa
    inner join Attributes a on a.Attribute_ID = pa.Attribute_ID
where 
    a.Attribute_ID = 15
    and CONVERT(DATETIME, pa.Attribute_Value) < GETDATE()
Run Code Online (Sandbox Code Playgroud)

更新 感谢大家的答案.我发现很难真正选择正确的答案,因为每个人都指出了一些对理解问题有用的东西.这绝对与执行的顺序有关.事实证明我的第一个查询正常工作,因为首先执行WHERE子句,然后执行SELECT.由于相同的原因,我的第二个查询失败(因为未过滤属性,执行相同的WHERE子句时转换失败).我的第三个查询是有效的,因为ID是索引(PK)的一部分,所以它优先,并且首先在该条件下钻取结果.

谢谢!

sql datetime where-clause sql-server-2008

10
推荐指数
2
解决办法
1万
查看次数

在SQL Server 2008中计算对数时出现无效的浮点运算错误

在Microsoft SQL Server 2008中,我有一个表,比如说myTable,包含大约600k行(实际上,它是连接其他几个表的结果,但我认为这并不重要).它的一个列,比如value数字类型(6,2).

简单的查询SELECT value FROM myTable ORDER BY value当然返回大约600k的数字,从1.01(即最低)开始,到70.00(最高)结束; 没有NULLs或其他值.

请注意,所有这些值都是数字和正数.但是,在调用时SELECT LOG(value) FROM myTable,我收到错误消息"发生了无效的浮点运算".

运行查询约3分钟后,始终显示此错误.将600k值复制到Excel并计算其LN()时,绝对没有问题.

我试过转换value成真实版或浮动版,这根本没用.最后我找到了一个解决方法:SELECT LOG(CASE WHEN value>0 THEN value ELSE 1 END) FROM myTable.这有效.但是,当所有价值观都是积极的时候呢?我试图取结果并将对数与Excel计算的对数进行比较 - 它们都是相同的(在某些行中只出现10 ^( - 15)或更小的顺序的差异,这几乎肯定是由不同的准确度给出的) .这意味着声明中的条件CASE总是正确的,我想.

有谁知道为什么会出现这个错误?任何帮助赞赏.谢谢.

sql sql-server-2008

8
推荐指数
1
解决办法
6345
查看次数

CASE结构的奇怪行为

背景:我试图在创建虚拟数据时获得一些随机的"十六进制"值,并提出了这种结构:

SELECT TOP 100 
   result = (CASE ABS(Binary_Checksum(NewID())) % 16 
                WHEN -1 THEN 'hello'
                WHEN 0 THEN '0' 
                WHEN 1 THEN '1' 
                WHEN 2 THEN '2' 
                WHEN 3 THEN '3'
                WHEN 4 THEN '4' 
                WHEN 5 THEN '5' 
                WHEN 6 THEN '6' 
                WHEN 7 THEN '7'
                WHEN 8 THEN '8' 
                WHEN 9 THEN '9' 
                WHEN 10 THEN 'a' 
                WHEN 11 THEN 'b'
                WHEN 12 THEN 'c' 
                WHEN 13 THEN 'd' 
                WHEN 14 THEN 'e' 
                WHEN 15 THEN 'f' 
                ELSE 'huh' …
Run Code Online (Sandbox Code Playgroud)

t-sql sql-server sql-server-2008

8
推荐指数
2
解决办法
188
查看次数

在执行SQL语句时,可以在过滤之前应用标量函数吗?

我想我总是天真地认为SQL查询的select部分中的标量函数只会应用于满足where子句所有条件的行.

今天我正在调试供应商提供的一些代码并且让这个假设受到挑战.我能想到这个代码失败的唯一原因是,对于本应由WHERE子句过滤掉的数据调用了Substring()函数.但似乎在过滤发生之前应用了子串调用,查询失败.这是我的意思的一个例子.假设我们有两个表,每个表有2列,分别有2行和1行.每个中的第一列只是一个id.NAME只是一个字符串,NAME_LENGTH告诉我们名称中具有相同ID的字符数.请注意,只有具有多个字符的名称在LONG_NAMES表中具有相应的行.

NAMES: ID, NAME
    1, "Peter"
    2, "X"
LONG_NAMES: ID, NAME_LENGTH
    1, 5
Run Code Online (Sandbox Code Playgroud)

如果我想要一个查询来打印最后3个字母的每个名字,我可能会先尝试这样的事情(现在假设是SQL Server语法):

SELECT substring(NAME,1,len(NAME)-3)
    FROM NAMES;
Run Code Online (Sandbox Code Playgroud)

我很快就会发现这会给我一个错误,因为当它到达"X"时它将尝试在子串调用中使用负数,它将失败.我的供应商决定解决这个问题的方法是过滤掉字符串太短以至于len-3查询无效的行.他通过加入另一张桌子来做到这一点:

SELECT substring(NAMES.NAME,1,len(NAMES.NAME)-3) 
    FROM NAMES 
        INNER JOIN LONG_NAMES 
            ON NAMES.ID = LONG_NAMES.ID;
Run Code Online (Sandbox Code Playgroud)

乍一看,这个查询看起来可能有效.连接条件将消除任何具有足够短的NAME字段以使子字符串调用失败的行.

但是,根据我的观察,SQL Server有时会尝试计算表中所有内容的子字符串表达式,然后应用连接来过滤掉行.这应该是这样发生的吗?是否有记录的操作顺序,我可以在何时发现某些事情?它是特定于特定的数据库引擎还是SQL标准的一部分?如果我决定在我的NAMES表中包含一些谓词来过滤短名称(如len(NAME)> 3),SQL Server是否也可以选择在尝试应用子字符串后应用它?如果是这样,那么做一个子串的唯一安全方法似乎是将它包装在select中的"case when"构造中?

sql sql-server scalar join

5
推荐指数
1
解决办法
1279
查看次数

无法将值转换为float

我们有一个SQL在ColumnA上执行CAST功能(到FLOAT).SQL有一个过滤器,它最终将间接过滤掉ColumnA中具有非数值的那些行.但是,由于我认为由于在并行中运行部分SQL,我相信CAST甚至应用于被过滤掉的行,这会导致SQL失败"无法将值转换为float ... "

我知道如果我通过添加查询提示运行一个proc

OPTION (MAXDOP 1)
Run Code Online (Sandbox Code Playgroud)

SQL按预期运行.我怀疑在1 proc上运行会强制应用过滤器以使用columnA中的非数值来清除行,以便其值的CASTING成功.我还发现使用查询提示

OPTION (FORCE ORDER)
Run Code Online (Sandbox Code Playgroud)

修复问题,我假设因为这也确保首先应用过滤器,并且我在一个柱面上运行的查询性能要好得多.

我倾向于使用第二个选项解决问题.如果我对这里发生的事情有任何误解,或者有人想阐述我的一般理解或提出建议,我将不胜感激.

我正在跑步

Microsoft SQL Server 2008 R2(RTM) - 10.50.1720.0(X64)2010年6月12日01:34:59版权所有(c)Windows NT 5.2上的Microsoft Corporation Enterprise Edition(64位)(Build 3790:Service Pack 2)

事后的想法:

似乎T-SQL具有以下函数来检查是否可以将字符串转换为特定数据类型.

IsFloat IsNumeric IsInteger等

我真的很烦恼我在数据库中找到的各种数据列中有多少列被定义为varchar(255).我想解决方案是"不要那样做!"

sql sql-server-2008

5
推荐指数
1
解决办法
2842
查看次数