關於SQL Server中的字元儲存的問題的測試

iSQlServer發表於2009-12-30

突然想到了資料庫中varchar和nvarchar以及字串字首'N'在實際應用中的問題,便做了一個小測試。測試的結論是我根據執行結果得出的。不完全正確,還請高手指點。

測試環境:windows server 2003 sp2 + sqlserver 2008 rtm

以下為測試的SQL語句:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gt-- Create Table
USE DBUser;

IF OBJECT_ID('dbo.Test','U') IS NOT NULL
DROP TABLE dbo.Test;

CREATE TABLE dbo.Test
(
nvarStr
NVARCHAR(2) NULL,
varStr
VARCHAR(2) NULL,
rowNum
INT NULL
);

-- Get DataLength
SELECT length_DATALENGTH_1 = DATALENGTH('li');
SELECT length_DATALENGTH_2 = DATALENGTH('lili');
SELECT length_DATALENGTH_3 = DATALENGTH(N'li');
SELECT length_DATALENGTH_4 = DATALENGTH(N'lili');
SELECT length_DATALENGTH_5 = DATALENGTH('李培');
SELECT length_DATALENGTH_6 = DATALENGTH(N'李培');

-- INSERT Data
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('li','li',1);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'li',N'li',2);

INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('lili','li',3);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'lili',N'li',4);

INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('li','李培',5);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'li',N'李培',6);

INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('李培','li',7);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'李培',N'li',8);

INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('李培','李培',9);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'李培',N'李培',10);

INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES('李培','',11);
INSERT INTO dbo.Test(nvarStr,varStr,rowNum) VALUES(N'李培',N'',12);

-- Query Data
SELECT * FROM dbo.Test;

---------------------------------------------------------

Get DataLength的結果為:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtlength_DATALENGTH_1:2
length_DATALENGTH_2:
4
length_DATALENGTH_3:
4
length_DATALENGTH_4:
8
length_DATALENGTH_5:
4
length_DATALENGTH_6:
4

由生成的結果可知:
在SQLServer2008中,對於漢字和英文字母的儲存:
漢字:無論字串前面是否加有字首'N',都將中文隱式轉換為有'N'的型別,即Unicode字元,因為只有UniCode字元才能表示中文,1個字元佔2個位元組(即1個漢字佔2個位元組)。
字母:有無字首'N'的情況不同。當沒有字首'N'時,預設採用ASCII的方式編碼,1個字元佔1個位元組(即1個字母佔1個位元組);當有字首'N'時,則採用Unicode的方式編碼,1個字元佔2個位元組(即1個字母佔2個位元組)。

INSERT Data的結果為:

<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--&gtnvarStr varStr rowNum
li li
1
li li
2
李培 li
7
李培 li
8
李培 李
11
李培 李
12

未插入行的報錯資訊皆為“將截斷字串或二進位制資料”。
由此可推論出:
SQLServer對於插入資料庫中資料的長度在兩方面同時加以限制:一、設定的最大字元數;二、由最大字元數得到的相應型別的最大位元組數。

由第2條插入語句的成功執行可推測出:
在某些情況下,即使英文字母前帶有字首'N',資料庫引擎在執行插入時有可能將資料隱式轉換成ASCII格式,以能夠將資料插入到資料庫。

 

因此,我們也可以知道,在建立表定義列時,為varchar和nvarchar指定的長度,既是在限定字元數,也是在限定位元組數。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-623980/,如需轉載,請註明出處,否則將追究法律責任。

相關文章