簡體   English   中英

varchar列的行為類似於char列-為什么?

[英]A varchar column is behaving like a char column - why?

我正在開發一個舊應用程序(為我的罪過!),它從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) 這將解釋如何用空格填充某些行值。

SQL Server的LEN()函數將列視為varchar(40)因為所有行的最大長度為13。

通過LINQ-to-SQL查找所有條形碼的最大長度時,提供程序將創建與上述SQL查詢類似的查詢(這將解釋相似的結果)。

出於某種原因,當通過LINQ-to-SQL查詢數據時,在某些情況下,這些值被視為char(40) -也許最初是這樣定義的?

我的問題

有誰知道為什么我會看到這種行為? 如果/當列被重新定義為varchar(40)時,為什么SQL Server沒有“未填充” char(40)值?

為什么SQL Server的LEN()忽略某些列的填充空格? 此行為受某些數據庫/查詢選項控制嗎?

為什么LINQ-to-SQL不接受列類型和“ unpad”值的VarChar(40)定義?

這是預期的行為。 當表聲明為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。

您可能要檢查“空格”在下面是否都相同。 嘗試將值轉換為可以檢查此信息以確保確定的類型。

我尚未使用SQL Server 2000,但也許CAST(Bar_Code AS二進制文件)會為您提供此信息?

SQL Server 2000 Cast and Convert參考: http : //msdn.microsoft.com/zh-cn/library/aa226054(v=sql.80).aspx

抱歉,我對LINQ不太熟悉,但是看來它使用的是=>表示法的某種指針。 如果是這樣,是否有可能無法正確終止該字符串並在遇到已知的終止符之前進入另一個“內存區域”? 我只是對此表示懷疑,因為我希望在這種情況下,計數值會發生變化,但這是需要考慮的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM