鉴于此数据:
CREATE TABLE tmpTable(
fldField varchar(10) null);
INSERT INTO tmpTable
SELECT 'XXX'
UNION ALL
SELECT 'XXX'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'YYY'
SELECT
CASE WHEN fldField like 'YYY' THEN 'OTH' ELSE 'XXX' END AS newField
FROM tmpTable
预期结果集为:
XXX
XXX
XXX
XXX
OTH
什么情况会导致SQL Server 2000找不到'YYY'?并返回以下结果集:
XXX
XXX
XXX
XXX
XXX
问题在于'YYY',我找到了其他方法来编写它以使其工作,但我想知道为什么这个确切的方法不起作用。另一个困难是它适用于我的大多数SQL Server 2000环境。我需要找出它们之间的不同之处。谢谢你的帮助。
答案 0 :(得分:1)
我在SQL 2000框上运行代码并得到相同的结果。不仅如此,当我运行一些额外的代码进行测试时,我得到了一些非常奇怪的结果:
CREATE TABLE dbo.TestLike ( my_field varchar(10) null);
GO
CREATE CLUSTERED INDEX IDX_TestLike ON dbo.TestLike (my_field)
GO
INSERT INTO dbo.TestLike (my_field) VALUES ('XXX')
INSERT INTO dbo.TestLike (my_field) VALUES ('XXX')
INSERT INTO dbo.TestLike (my_field) VALUES ('ZZZ')
INSERT INTO dbo.TestLike (my_field) VALUES ('ZZZ')
INSERT INTO dbo.TestLike (my_field) VALUES ('YYY')
GO
SELECT
my_field,
case my_field when 'YYY' THEN 'Y' ELSE 'N' END AS C2,
case when my_field like 'YYY' THEN 'Y' ELSE 'N' END AS C3,
my_field
FROM dbo.TestLike
GO
我的结果:
my_field C2 C3 my_field
---------- ---- ---- ----------
N XXX N XXX
N XXX N XXX
Y YYY N YYY
N ZZZ N ZZZ
N ZZZ N ZZZ
注意my_field在同一行中有两个不同的值?我已经在办公室要求其他人给它一个快速测试。对我来说看起来像个错误。
答案 1 :(得分:1)
检查您的服务包。将我的SQL 2000框升级到SP4后,我现在可以根据您的情况获得正确的值。
我仍然收到我在之前的帖子中报告的交换数据:(
如果你SELECT @@version
,你应该得到8.00.2039。任何版本号都小于此值,您应该安装SP4。
答案 2 :(得分:0)
fldField = '%YYY%'
怎么样?
答案 3 :(得分:0)
它在我的SQL 2005安装上按预期工作。如果它适用于其他机器,听起来你有一个环境差异。尝试比较SQL Server Management Studio中的连接属性,以获得有效的连接和无法查看是否可以找出差异的连接。
答案 4 :(得分:0)
我是Oracle人员,而不是SQL * Server人员,但在我看来,您应该是: -
SELECT
CASE WHEN fldField like '%YYY%' THEN
'OTH'
ELSE 'XXX'
END AS newField
FROM
tmpTable
或......
SELECT
CASE WHEN fldField = 'YYY' THEN
'OTH'
ELSE 'XXX'
END AS newField
FROM
tmpTable
第二个是我要进入的方向,因为至少在Oracle中,等分解决的速度比想要快。
答案 5 :(得分:0)
如果在未指定任何搜索条件的情况下使用LIKE,则其行为类似于=比较。在您的示例中,我希望它能正常工作。在您的真实数据中,您的数据中可能包含隐藏(不可打印)字符(请考虑回车,换行,制表符等)。
看看这个例子......
Declare @tmpTable TABLE(
fldField varchar(10) null);
INSERT INTO @tmpTable
SELECT 'XXX'
UNION ALL
SELECT 'XXX'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'ZZZ'
UNION ALL
SELECT 'YYY'
UNION ALL
SELECT 'YYY' + Char(10)
SELECT CASE WHEN fldField like 'YYY' THEN 'OTH' ELSE 'XXX' END AS YourOriginalTest,
CASE WHEN fldField like 'YYY%' THEN 'OTH' ELSE 'XXX' END AS newField
FROM @tmpTable
您会注意到我添加的最后一段数据是YYY和换行符。如果您选择此数据,您将不会注意到数据中的换行符,但它就在那里,因此您的LIKE条件(其作用类似于相同的条件)不匹配。
常见的“隐藏”字符是制表符,回车符和换行符。要确定这是否导致您的问题......
Select *
From Table
Where Column Like '%[' + Char(10) + Char(9) + Char(13) + ']%'
答案 6 :(得分:0)
多么可爱的小虫。我想我知道原因。如果我是对的,那么你将得到你期望的结果:
SELECT
CASE
WHEN fldField like 'YYY ' -- 7 spaces
THEN 'OTH'
ELSE 'XXX'
END as newField
from tmpTable
错误是varchar(10)的行为类似于char(10)。至于它为什么没有,你需要理解一个旧的琐事问题,即两个没有元字符的字符串是如何=但彼此不相似。
问题是char(10)在内部被认为是空间填充的。 like运算符不忽略这些空格。 =运算符应该是chars的情况。内存告诉我Oracle通常会忽略字符串的空格。 Postgres用铸造做了一些技巧。我没有使用SQL * Server,所以我无法告诉你它是如何做到的。
答案 7 :(得分:0)
通过向表达式添加(%),它可以正常工作。
SELECT
CASE
WHEN fldField like '%YYY%' THEN 'OTH'
ELSE 'XXX' END AS newField
END
答案 8 :(得分:-1)
您没有指定要选择的内容并检查CASE ...
SELECT CASE fldField WHEN 'YYY'
THEN 'OTH' ELSE 'XXX' END AS newField FROM tmpTable