Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.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
C# SQL执行错误。将数据类型nvarchar转换为实数时出错_C#_Sql - Fatal编程技术网

C# SQL执行错误。将数据类型nvarchar转换为实数时出错

C# SQL执行错误。将数据类型nvarchar转换为实数时出错,c#,sql,C#,Sql,目前,我正在对一个开始失败的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.Dat

目前,我正在对一个开始失败的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 
当我删除强制转换并执行查询时,它返回大约1400000行,因此我获取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++;
}
更新2:
从完整的原始视图粘贴上面的代码。

乍一看,您似乎没有将c代码连接到sql查询

下面的行将1stLinesOffline设置为字符串的空列表,但您从未将其设置为任何其他值,因此for循环将永远不会运行

List lstLinesOfFile=新列表()

我希望看到

列表1stLinesOfFile=mySqlResults


其中mySqlResults是SQL的结果数据集。

乍一看,您似乎没有将c代码连接到SQL查询

下面的行将1stLinesOffline设置为字符串的空列表,但您从未将其设置为任何其他值,因此for循环将永远不会运行

List lstLinesOfFile=新列表()

我希望看到

列表1stLinesOfFile=mySqlResults


其中,mySqlResults是SQL的结果数据集。

使用它可以确定哪些值不能被SQL解析

select * from tblBenchData where ISNUMERIC(DataValue) = 0
还是这个

select * from tblBenchData where DataValue like '%[a-Z]%'

我猜这可能是一个区域性问题(例如“,”vs“)

使用它来找出哪些值不能被SQL解析

select * from tblBenchData where ISNUMERIC(DataValue) = 0
还是这个

select * from tblBenchData where DataValue like '%[a-Z]%'

我猜可能是一个文化问题(例如“,”vs“)

您在该查询中使用了右外连接和左外连接语法;但您在右/左联接表上使用where子句。这有点恶心,可能没有达到你的预期

我首先在
tblBenchData
表中查看哪些DataSetID返回为null

比如:

SELECT *
  FROM tblDataSet
  WHERE DataSetID NOT EXISTS IN (SELECT DataSetID FROM tblBenchData)
接下来,我猜您在复制/粘贴时遗漏了一些内容,因为
tblBenchCode
上的左外部联接没有
on
条件。您能提供实际使用的查询吗

旁注:我不完全确定您为什么拥有
顶部(100%)部分。我知道在视图中允许order by定义是一个不可靠的把戏,但它在今天毫无意义,在您提供的查询中也毫无意义。。。除非这是一个古老的SQL server



另一种可能性是,正如Loud所指出的,一年前的问题表明您的值位于…

您在该查询中使用了右外和左外连接语法;但您在右/左联接表上使用where子句。这有点恶心,可能没有达到你的预期

我首先在
tblBenchData
表中查看哪些DataSetID返回为null

比如:

SELECT *
  FROM tblDataSet
  WHERE DataSetID NOT EXISTS IN (SELECT DataSetID FROM tblBenchData)
接下来,我猜您在复制/粘贴时遗漏了一些内容,因为
tblBenchCode
上的左外部联接没有
on
条件。您能提供实际使用的查询吗

旁注:我不完全确定您为什么拥有
顶部(100%)部分。我知道在视图中允许order by定义是一个不可靠的把戏,但它在今天毫无意义,在您提供的查询中也毫无意义。。。除非这是一个古老的SQL server



另一种可能性是,正如Loud指出的,您一年前的问题表明您的值在…

中。出现此问题的原因是有大量奇数字符串将通过
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

出现此问题的原因是,有大量奇数字符串将通过
ISNUMERIC()
测试,但无法将
CAST()
转换为float(并且仍然可以通过
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
上面的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.
当我执行这些命令时,它们