数据表的问题选择语句

时间:2012-03-07 11:53:55

标签: c# vb.net select datatable

以下VB行,其中_DSversionInfo是DataSet,不返回任何行:

_DSversionInfo.Tables("VersionInfo").Select("FileID=88")

但检查显示该表包含FileID为92,93,94,90,88,89,215,216的行。表列都是字符串类型。

进一步调查显示,如果引用该号码,使用ID为88,215和216将仅返回行。

_DSversionInfo.Tables("VersionInfo").Select("FileID='88'")

无论是否引用该号码,所有其他行都有效。

任何人都有一个解释为什么这会发生在一些数字而不是其他数字?我明白应该引用这些数字而不是为什么有些工作和其他工作没有?

我在一些VB.NET代码中发现了这一点但是(尽管我最初的指责)并不认为它是VB.NET特有的。

4 个答案:

答案 0 :(得分:20)

根据MSDN documentation on building expressions,应始终引用字符串。如果不这样做会产生一些奇怪的不可预测的行为......你应该引用你的数字字符串来获得可预测和正确的行为,就像文档所说的那样。

我已经描述了你过去所描述的内容,并且有点试图弄清楚 - 在这里,弹出你最喜欢的.NET编辑器并尝试以下内容:

创建一个DataTable,并在该DataSet的字符串列'Stuff'中,按以下顺序插入行:“6”,“74”,“710”,并选择过滤器表达式“Stuff = 710”。你将获得1排。现在,将第一行更改为任何大于7的数字 - 突然,你会得到0行。

只要使用字符串排序逻辑以正确的降序排序数字(即,在599之后出现7),未加引号的查询似乎有效。

我的猜测是,这是对DataSet过滤器表达式的解析方式的限制,并不意味着以这种方式工作......

守则:

            // Unquoted filter string bizzareness.
            var table = new DataTable();

            table.Columns.Add(new DataColumn("NumbersAsString", typeof(String)));

            var row1 = table.NewRow(); row1["NumbersAsString"] = "9"; table.Rows.Add(row1); // Change to '66
            var row2 = table.NewRow(); row2["NumbersAsString"] = "74"; table.Rows.Add(row2);
            var row4 = table.NewRow(); row4["NumbersAsString"] = "90"; table.Rows.Add(row4);
            var row3 = table.NewRow(); row3["NumbersAsString"] = "710"; table.Rows.Add(row3);

            var results = table.Select("NumbersAsString = 710"); // Returns 0 rows.
            var results2 = table.Select("NumbersAsString = 74"); // Throws exception "Min (1) must be less than or equal to max (-1) in a Range object." at System.Data.Select.GetBinaryFilteredRecords()

结论:基于最后一种情况中的异常文本,似乎在过滤器表达式中会出现一些不能保证安全的奇怪转换。通过让.NET知道这是一个文字来明确地在您查询的值周围放置单引号可以避免这个问题。

答案 1 :(得分:8)

DataTable在列上构建索引以快速进行Select()查询。该索引按值排序,然后使用二进制搜索来选择与查询表达式匹配的记录范围。

所以记录将按照215,216,88,89,90,92,93,94进行排序。完成二进制搜索将它们视为整数(根据我们的过滤器表达式)无法定位某些记录,因为它只能搜索正确排序的集合。

它将数据索引为字符串,二进制搜索搜索为数字。请参阅以下说明。

        string[] strArr = new string[] { "115", "118", "66", "77", "80", "81", "82" };
        int[] intArr = new int[] { 215, 216, 88, 89, 90, 92, 93, 94 };
        int i88 = Array.BinarySearch(intArr, 88); //returns -ve index
        int i89 = Array.BinarySearch(intArr, 89); //returns +ve index

这应该是框架中的错误。

答案 2 :(得分:0)

this error usually comes due to invalid data table column type in which you are going to search
i got this error when i was using colConsultDate instead of Convert(colConsultDate, 'System.DateTime')
because colConsultDate was a data table column of type string which i must have to convert into System.DateTime therefor your search query should be like 

    string query = "Convert(colConsultDate, 'System.DateTime') >= #" + sdateDevFrom.ToString("MM/dd/yy") + "# AND Convert(colConsultDate, 'System.DateTime') <= #" + sdateDevTo.ToString("MM/dd/yy") + "#";
   DataRow[] dr =  yourDataTable.Select(query);
   if (dr.Length > 0)
   {
      nextDataTabel = dr.CopyToDataTable();
   }

答案 3 :(得分:0)

@Pal Akkapeddi只想在你的答案中添加内容。

如果你做这样的事情,当你必须使用比较运算符时,它会受益。因为你在74附近加上引号它将被视为字符串。请通过实际编写代码来看待自己。 Comparison operators (十进制仅供参考,您可以添加所需的数据类型。)

var results2 = table.Select("Convert(NumbersAsString , 'System.Decimal') = 74.0")