我正在开发一个遗留应用程序(我的罪孽!),它始于Visual Basic 2.0(!),并已升级到Visual Basic 6.0,最近升级到.NET。
数据库服务器当前是SQL Server 2000(虽然我已将副本还原到本地SQL Server 2008 R2 Express实例,并且它在SQL Server 2000兼容模式下运行。)
该应用程序使用LINQ-to-SQL从数据库中检索实体。
一个特定的表定义为(为简洁起见,删除了其他列):
CREATE TABLE dbo.Bar_Code (
Bar_Code varchar(40) NOT NULL,
CONSTRAINT PK_BAR_CODE PRIMARY KEY CLUSTERED
(
Bar_Code ASC
)
它关联的LINQ-to-SQL实体被定义为服务器数据类型:VarChar(40) NOT NULL
当我在SQL Server Management Studio中执行以下SQL查询时:
SELECT MAX(LEN(Bar_Code))
FROM dbo.Bar_Code
结果是 13 。
使用LINQ-to-SQL我得到了一些意想不到的结果:
// get maximum length of all barcodes
var maxLength = dataContext.Bar_Codes.Max(barCode => barCode.Bar_Code.Length);
// maxLength == 13
// get list of all barcodes
var list = dataContext.Bar_Codes.ToList();
var length = list[0].BarCode.Length; // legnth = 13
var value = list[0].BarCode; // value = "9316165196376"
var length = list[1].BarCode.Length; // legnth = 13
var value = list[1].BarCode; // value = "9316165196371"
var length = list[2].BarCode.Length; // legnth = 40 <-- WTF?
var value = list[2].BarCode; // value = "9317585001669 "
因此,对于表中的某些值,它们表现为“正常” - 即varchar(40)
应该如此,但是有些行的数据行为类似于char(40)
列 - 例如作为上面的第三行。
在表格的有效期内,Bar_Code
的定义已从char(40)
更改为随后修改为varchar(40)
。这将解释带有空格的某些行值的padidng。
SQL Server的LEN()
函数将列视为varchar(40)
,因为所有行的最大长度为13。
当通过LINQ-to-SQL查找所有条形码的最大长度时,提供程序正在创建类似于上面的SQL查询的查询(这将解释类似的结果)。
由于某些原因,当通过LINQ-to-SQL查询数据时,在某些情况下,这些值被视为char(40)
- 可能是在它们最初被定义为这样的时候?
有谁知道我为什么会看到这种行为?如果/当列重新定义为char(40)
时,为什么SQL Server没有“未填充”varchar(40)
值?
为什么SQL Server的LEN()
会忽略某些列的填充空格?此行为是否由某些数据库/查询选项控制?
为什么LINQ-to-SQL不遵守列类型和“unpad”值的VarChar(40)
定义?
答案 0 :(得分:1)
这是预期的行为。当表被声明为char(40)时,数据被填充,当它被更改为varchar(40)时,服务器别无选择,只能假设列中的数据有效(即您想要空格) 。看看这个sql代码:
LEN忽略尾随空格http://msdn.microsoft.com/en-us/library/ms190329.aspx
create table test (id int identity(1,1), example char(20));
insert into test (example) values ('1');
alter table test alter column example varchar(20);
insert into test (example) values ('2 ');
insert into test (example) values ('3');
select '[' + example + ']', LEN(example) from test;
drop table test;
结果
[1 ] 1
[2 ] 1
[3] 1
如果您不想要空格,请执行修剪尾随空格的更新,或执行rtrim。
答案 1 :(得分:0)
您可能想要检查下方的“空格”是否都是相同的字符。尝试将值转换为可以检查此信息以确定的类型。
我没有使用过SQL Server 2000,但也许CAST(Bar_Code AS binary)可以提供这些信息吗?
SQL Server 2000转换和转换参考: http://msdn.microsoft.com/en-us/library/aa226054(v=sql.80).aspx
答案 2 :(得分:0)
我对LINQ并不熟悉,对不起,但似乎它正在使用=&gt;的某种指针。符号。如果这是真的,它可能是没有正确终止字符串并运行到另一个“内存区域”,直到它遇到一个已知的终结器?我持怀疑态度只是因为如果是这种情况我会期望计数值发生变化,但这是需要考虑的事情。