目前,我正在解决开始失败的SQL Server 2008查询。这是查询:
SELECT TOP (100) PERCENT dbo.tblBenchmarkData.FieldDataSetID, dbo.tblBC.BCID, CAST(dbo.tblBenchmarkData.DataValue AS float(8)) AS DataValue,
dbo.tblBC.BCMnemonic, dbo.tblDataType.DataTypeMnemonic
FROM dbo.tblFieldDataSet RIGHT OUTER JOIN
dbo.tblBenchmarkData ON dbo.tblFieldDataSet.FieldDataSetID = dbo.tblBenchmarkData.FieldDataSetID LEFT OUTER JOIN
dbo.tblBC LEFT OUTER JOIN
dbo.tblDataType ON dbo.tblBC.DataTypeID = dbo.tblDataType.DataTypeID RIGHT OUTER JOIN
dbo.tblZEGCode ON dbo.tblBC.BCID = dbo.tblZEGCode.BCID ON dbo.tblBenchmarkData.ZEGCodeID = dbo.tblZEGCode.ZEGCodeID
WHERE (dbo.tblDataType.DataTypeID = '{5951994B-BF47-4117-805D-B8F85FAB76A8}') AND (dbo.tblFieldDataSet.OriginalFieldDataSetID IS NULL) AND
(dbo.tblFieldDataSet.Duplicate = 0)
ORDER BY dbo.tblBC.BCMnemonic, DataValue
当我删除强制转换并执行查询时,它返回大约1 400 000行,因此我获取DataValue结果并针对此输出运行一个小型C#程序,以验证所有数据实际上都是数字:
List<String> lstLinesOfFile = new List<string>();
Int64 intLineCounter = 0;
ReadFile("data.txt");
double dblNum;
foreach (string strValue in lstLinesOfFile)
{
bool isNum = double.TryParse(strValue, out dblNum);
if (!isNum)
{
Debug.WriteLine("Line: " + Convert.ToString(intLineCounter) + ", Value = " + strValue);
}
intLineCounter++;
}
该程序表明没有数据行不是数字,所以有人有任何建议,为什么我会收到此错误? TIA。
更新:
这是我编写的代码,用于验证它是否正在检查每一行数据:
List<String> lstLinesOfFile = new List<string>();
Int64 intLineCounter = 0;
ReadFile("data.txt");
double dblNum;
foreach (string strValue in lstLinesOfFile)
{
bool isNum = double.TryParse(strValue, out dblNum);
if (!isNum)
{
Debug.WriteLine("Line: " + Convert.ToString(intLineCounter) + ", Value = " + strValue);
}
else
{
Debug.WriteLine("Line: " + Convert.ToString(intLineCounter) + ", Number = " + strValue);
}
intLineCounter++;
}
这给出了如下结果:
....
Line: 241564, Number = 1843.2
Line: 241565, Number = 18430
Line: 241566, Number = 18430.9
Line: 241567, Number = 18431.6
Line: 241568, Number = 18433.9
Line: 241569, Number = 1844.52
....
更新2: 从完整的原始视图粘贴上面的代码。
答案 0 :(得分:2)
使用它来确定SQL无法解析哪些值
select * from tblBenchData where ISNUMERIC(DataValue) = 0
或者
select * from tblBenchData where DataValue like '%[a-Z]%'
我的猜测是文化问题(例如“,”vs“。”)
答案 1 :(得分:2)
出现此问题是因为奇数字符串数量惊人,将通过ISNUMERIC()
测试,但无法CAST()
浮动(并且仍可通过double.TryParse
转换) 。我所知道的三个是:
这是捕捉其中一些的一种方法:
SELECT DataValue
FROM dbo.tblBenchData
WHERE ISNUMERIC('0'+DataValue) = 0
奇怪的是,这将正确转换或拒绝大部分而不会出错:
SELECT CAST('0'+DataValue As float(8)) As DataValue
FROM dbo.tblBenchData
WHERE ISNUMERIC('0'+DataValue) = 0
但仍有一些奇怪的案例可以通过。
好的,我忘记了这个技巧不喜欢有效的负面价值。
而且,对于“其他”奇怪的情况,我真的不记得他们所有,也没有看到他们在任何地方列出(真的很讨厌,我知道)。但是,大多数问题字符串来自各种不同的数字解析器如何查看所谓的“退化情况”,即单个字符串。
因此,尝试解决这两个问题的一种方法是预先检查长度为1的字符串,然后专门处理它们。因此,将原始查询更改为类似的内容应该有效:
;WITH cteBench As
(
SELECT *
, CASE
WHEN DataValue IN('-','.','+') THEN '0'
WHEN Len(DataValue) = 1 AND DataValue BETWEEN '0' And '9'
THEN DataValue
WHEN Len(DataValue) = 1 THEN ''
WHEN DataValue LIKE '-%' THEN DataValue
ELSE '0'+DataValue
END As FixedDataValue
FROM dbo.tblBenchmarkData.DataValue
)
SELECT TOP (100) PERCENT cteBench.FieldDataSetID, dbo.tblBC.BCID, CAST(cteBench.FixedDataValue AS float(8)) AS DataValue,
dbo.tblBC.BCMnemonic, dbo.tblDataType.DataTypeMnemonic
FROM dbo.tblFieldDataSet RIGHT OUTER JOIN
cteBench ON dbo.tblFieldDataSet.FieldDataSetID = cteBench.FieldDataSetID LEFT OUTER JOIN
dbo.tblBC LEFT OUTER JOIN
dbo.tblDataType ON dbo.tblBC.DataTypeID = dbo.tblDataType.DataTypeID RIGHT OUTER JOIN
dbo.tblZEGCode ON dbo.tblBC.BCID = dbo.tblZEGCode.BCID ON cteBench.ZEGCodeID = dbo.tblZEGCode.ZEGCodeID
WHERE (dbo.tblDataType.DataTypeID = '{5951994B-BF47-4117-805D-B8F85FAB76A8}')
AND (dbo.tblFieldDataSet.OriginalFieldDataSetID IS NULL)
AND (dbo.tblFieldDataSet.Duplicate = 0)
AND ISNUMERIC(FixedDataValue) = 1
ORDER BY dbo.tblBC.BCMnemonic, DataValue
答案 2 :(得分:1)
您在该查询中有一个正确的外部和外部联接语法;但是你在右/左连接表上使用了where子句。这有点讨厌,可能没做你期望的事情。
我首先看到DataSetID在tblBenchData
表中返回为null。
类似的东西:
SELECT *
FROM tblDataSet
WHERE DataSetID NOT EXISTS IN (SELECT DataSetID FROM tblBenchData)
接下来,我猜你错过了复制/粘贴的内容,因为ON
上的左外连接没有tblBenchCode
条件。你能提供实际的查询吗?
旁注:我不完全确定为什么你有TOP(100) PERCENT
件。我知道在视图定义中允许顺序是一个不可靠的技巧,但它今天毫无意义,在你提供的查询中毫无意义......除非这是一个古老的SQL服务器。
另一种可能性是,正如Loud指出的那样,你一年前提出的问题表明你的价值在scientific notation ......
答案 3 :(得分:0)
乍一看,您似乎没有将c#代码连接到sql查询。
下面的行将1stLinesOffline设置为一个空的字符串列表,但是你从未将它设置为其他任何东西,因此for循环永远不会运行。
列出lstLinesOfFile = new List();
我希望看到
列出1stLinesOfFile = mySqlResults;
其中mySqlResults是SQL的结果数据集。
答案 4 :(得分:0)
以上SELECT TOP(100)PERCENT dbo.tblBenchmarkData.FieldDataSetID,dbo.tblBC.BCID ...实际上是一个名为qryFieldParameterBCNumericLookup的视图。当我执行此命令时:
SELECT TOP 100 * FROM MyDatabase.dbo.qryFieldParameterBCNumericLookup
我收到错误:
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to real.
当我执行这些命令中的任何一个时,它们都可以正常工作而没有错误:
SELECT * FROM MyDatabase.dbo.qryFieldParameterBCNumericLookup
SELECT TOP 50 * FROM MyDatabase.dbo.qryFieldParameterBCNumericLookup
SELECT TOP 1000 * FROM MyDatabase.dbo.qryFieldParameterBCNumericLookup