??xml version="1.0" encoding="utf-8" standalone="yes"?>
/*Ƣ迎转蝲Q请保留本声明信?/p>
/*作者:?彦?enhydraboy@yahoo.com.cn
/*------------------------------------------------------------------------------------
q是一个在我实际一个项目中遇到的问题?3BHL01001Q上P?3BHL01001(上v)比较的结果是一L。导致引L重复的主键问题?/p>
03BHL01001Q上P?3BHL01001(上v)差别Q就在于前者的括号是全角的括号字符Q后者是半角的括号字W。全角的括号字符和半角的括号字符的ascii码显然是不一L。全角的Q?ASCII码是0xA3A8 Q而半角的( ?x28。那么ؓ什么SQL Server会认为是一L呢?
问题其实出在数据库的排序规则上Q让我们在仔l研M下SQL Server的文档。SQL Server的排序规则由q样几部分组成,代码c区分大写、区分重韟뀁区分宽度。最后一个在SQL Server的联机帮助中没有q一步提及,其实本篇遇到的问题就是由于这个原因造成的。区分宽度:指定 SQL Server 区分相同字符的单字节表示法(半角Q和双字节表C法Q全角)。如果没有选择Q则 SQL Server 认为相同字W的单字节表C法和双字节表示法等效?/p>
~省Q安装SQL Server中文版的时候,SQL Server帮你选择的排序规则是Chinese_PRC_CI_AS(Chinese-PRC, case-insensitive, accent-sensitive, kanatype-insensitive, width-insensitive),是中文,不区分大写、区分重韟뀁不区分假名、不区分宽度。因此,自然p?3BHL01001Q上P=03BHL01001(上v)?/p>
所以,正确的选择应该是,后缀为WS的中文排序规则。本例中我们应该选择Chinese_PRC_CI_AS_WS?/p>
我们来看一下,指定排序规则是Chinese_PRC_CI_AS_WS后,怎么样了Q?/p>
select 1 where '03BHL01001Q上P'='03BHL01001(上v)'
collate Chinese_PRC_CI_AS_WS
-----------
Q所影响的行Cؓ 0 行)
看来q个问题解决了?/p>
重要提示Q?/b>
如何察看使用那个排序规则呢?可以使用下面的SQL语句?/p>
SELECT *
FROM ::fn_helpcollations()
可以查询所有排序规则的信息?/p>
查出所有中文排序规则的信息
SELECT * FROM
(
SELECT *
FROM ::fn_helpcollations()) A
WHERE name like 'Chinese%'
TIMESTAMP列类?br />TIMESTAMP值可以从1970的某时的开始一直到2037q__ֺZU,其g为数字显C?br />TIMESTAMP值显C尺寸的格式如下表所C:
Q?br />+---------------+----------------+
| 列类型 ?| 昄格式 |
| TIMESTAMP(14) | YYYYMMDDHHMMSS |
| TIMESTAMP(12) | YYMMDDHHMMSS |
| TIMESTAMP(10) | YYMMDDHHMM |
| TIMESTAMP(8) | YYYYMMDD |
| TIMESTAMP(6) | YYMMDD |
| TIMESTAMP(4) | YYMM |
| TIMESTAMP(2) | YY |
+---------------+----------------+
“完整”TIMESTAMP格式?4位,但TIMESTAMP列也可以用更短的昄寸创?br />最常见的显C尺寸是6??2、和14?br />你可以在创徏表时指定一个Q意的昄寸Q但是定义列长ؓ0或比14大均会被强制定义为列?4?br />列长在从1?3范围的奇数值尺寸均被强制ؓ下一个更大的偶数?/p>
列如Q?br />定义字段长度 强制字段长度
TIMESTAMP(0) -> TIMESTAMP(14)
TIMESTAMP(15)-> TIMESTAMP(14)
TIMESTAMP(1) -> TIMESTAMP(2)
TIMESTAMP(5) -> TIMESTAMP(6)
所有的TIMESTAMP列都有同L存储大小Q?br />使用被指定的时期旉值的完整_ֺQ?4位)存储合法的g考虑昄寸?br />不合法的日期Q将会被强制?存储
q有几个含意Q?
1、虽然你时定义了列TIMESTAMP(8)Q但在你q行数据插入与更新时TIMESTAMP?br /> 实际上保存了14位的数据Q包括年月日时分U)Q?br /> 只不q在你进行查询时MySQLq回l你的是8位的q月日数据?br /> 如果你用ALTER TABLE拓宽一个狭H的TIMESTAMP列,以前被“隐蔽”的信息被昄?
2、同P~小一个TIMESTAMP列不会导致信息失去,除了感觉上值在昄Ӟ较少的信息被昄出?
3、尽TIMESTAMPD存储为完整精度,直接操作存储值的唯一函数是UNIX_TIMESTAMP()Q?br /> ׃MySQLq回TIMESTAMP列的列值是q过格式化后的检索的|
q意味着你可能不能用某些函数来操作TIMESTAMP列(例如HOUR()或SECOND()Q,
除非TIMESTAMP值的相关部分被包含在格式化的g?br /> 例如Q一个TIMESTAMP列只有被定义为TIMESTAMP(10)以上ӞTIMESTAMP列的HH部分才会被显C,
因此在更短的TIMESTAMPg使用HOUR()会生一个不可预知的l果?br /> 4、不合法TIMESTAMPD变换到适当cd的“零”?00000000000000)。(DATETIME,DATE亦然Q ?
你可以用下列语句来验证Q?br />CREATE TABLE test ('id' INT (3) UNSIGNED AUTO_INCREMENT, 'date1' TIMESTAMP (8) PRIMARY KEY('id'));
INSERT INTO test SET id = 1;
SELECT * FROM test;
+----+----------------+
| id | date1 |
+----+----------------+
| 1 | 20021114 |
+----+----------------+
ALTER TABLE test CHANGE 'date1' 'date1' TIMESTAMP(14);
SELECT * FROM test;
+----+----------------+
| id | date1 |
+----+----------------+
| 1 | 20021114093723 |
+----+----------------+
你可以用TIMESTAMP列类型自动地用当前的日期和时间标记INSERT或UPDATE的操作?br />如果你有多个TIMESTAMP列,只有W一个自动更新?
自动更新W一个TIMESTAMP列在下列M条g下发生:
1、列值没有明地在一个INSERT或LOAD DATA INFILE语句中指定?
2、列值没有明地在一个UPDATE语句中指定且另外一些的列改变倹{?br /> Q注意一个UPDATE讄一个列为它已经有的|
q将不引起TIMESTAMP列被更新Q?br /> 因ؓ如果你设|一个列为它当前的|MySQLZ效率而忽略更攏V)
3、你明确地设定TIMESTAMP列ؓNULL.
4、除W一个以外的TIMESTAMP列也可以讄到当前的日期和时_只要列设ؓNULLQ或NOW()?/p>
CREATE TABLE test (
'id' INT (3) UNSIGNED AUTO_INCREMENT,
'date1' TIMESTAMP (14),
'date2' TIMESTAMP (14),
PRIMARY KEY('id')
);
INSERT INTO test (id, date1, date2) VALUES (1, NULL, NULL);
INSERT INTO test SET id= 2;
+----+----------------+----------------+
| id | date1 | date2 |
+----+----------------+----------------+
| 1 | 20021114093723 | 20021114093723 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->W一条指令因设date1、date2为NULL,所以date1、date2值均为当前时?br /> W二条指令因没有设date1、date2列|W一个TIMESTAMP列date1为更Cؓ当前旉Q?br /> 而二个TIMESTAMP列date2因日期不合法而变为?0000000000000?/p>
UPDATE test SET id= 3 WHERE id=1;
+----+----------------+----------------+
| id | date1 | date2 |
+----+----------------+----------------+
| 3 | 20021114094009 | 20021114093723 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->q条指o没有明确地设定date2的列|所以第一个TIMESTAMP列date1被更新为当前时?/p>
UPDATE test SET id= 1,date1=date1,date2=NOW() WHERE id=3;
+----+----------------+----------------+
| id | date1 | date2 |
+----+----------------+----------------+
| 1 | 20021114094009 | 20021114094320 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->q条指o因设定date1=date1Q所以在更新数据时date1列值ƈ不会发生改变
而因讑֮date2=NOW()Q所以在更新数据时date2列g被更Cؓ当前旉
此指令等效ؓ UPDATE test SET id= 1,date1=date1,date2=NULL WHERE id=3;
因MySQLq回?TIMESTAMP 列ؓ数字昄形式Q?br />你可以用DATE_FROMAT()函数来格式化 TIMESTAMP ?/p>
SELECT id,DATE_FORMAT(date1,'%Y-%m-%d %H:%i:%s') As date1,
DATE_FORMAT(date2,'%Y-%m-%d %H:%i:%s') As date2 FROM test;
+----+---------------------+---------------------+
| id | date1 | date2 |
+----+---------------------+---------------------+
| 1 | 2002-11-14 09:40:09 | 2002-11-14 09:43:20 |
| 2 | 2002-11-14 09:37:24 | 0000-00-00 00:00:00 |
+----+---------------------+---------------------+
SELECT id,DATE_FORMAT(date1,'%Y-%m-%d') As date1,
DATE_FORMAT(date2,'%Y-%m-%d') As date2 FROM test;
+----+-------------+-------------+
| id | date1 | date2 |
+----+-------------+-------------+
| 1 | 2002-11-14 | 2002-11-14 |
| 2 | 2002-11-14 | 0000-00-00 |
+----+-------------+-------------+
在某U程度上Q你可以把一U日期类型的Dl一个不同的日期cd的对象?br />然而,而尤其注意的是:值有可能发生一些改变或信息的损失:
1、如果你一个DATEDl一个DATETIME或TIMESTAMP对象Q?br /> l果值的旉部分被设|ؓ'00:00:00'Q?br /> 因ؓDATEg不包含有旉信息?
2、如果你一个DATETIME或TIMESTAMPDl一个DATE对象Q?br /> l果值的旉部分被删除,因ؓDATEcd不存储时间信息?
3、尽DATETIME, DATE和TIMESTAMP值全都可以用同样的格式集来指定,
但所有类型不都有同样的D围?br /> 例如QTIMESTAMPg能比1970早,也不能比2037晚,
q意味着Q一个日期例?1968-01-01'Q当作ؓ一个DATETIME或DATE值时它是合法的,
但它不是一个正TIMESTAMP|q且如果这L一个对象赋值给TIMESTAMP列,它将被变换ؓ0?
当指定日期值时Q当心某些缺P
1、允怽为字W串指定值的宽松格式能被ƺ骗?br /> 例如Q,因ؓ?”分隔符的用,?10:11:12'可能看v来像旉|
但是如果在一个日期中使用Q上下文作为年份被解释?2010-11-12'?br /> ?10:45:15'被变换?0000-00-00'Q因?45'不是一个合法的月䆾?
2、以2位数字指定的q值是模糊的,因ؓ世纪是未知的?br /> MySQL使用下列规则解释2位年|
?0-69范围的年D变换?000-2069?
在范?0-99的年D变换?970-1999?
Sql Server中的日期与时间函?
1. 当前pȝ日期、时?
select getdate()
2. dateadd 在向指定日期加上一D|间的基础上,q回新的 datetime ?br />例如Q向日期加上2?
select dateadd(day,2,'2004-10-15') --q回Q?004-10-17 00:00:00.000
3. datediff q回跨两个指定日期的日期和时间边界数?br />select datediff(day,'2004-09-01','2004-09-18') --q回Q?7
4. datepart q回代表指定日期的指定日期部分的整数?br />SELECT DATEPART(month, '2004-10-15') --q回 10
5. datename q回代表指定日期的指定日期部分的字符?br />SELECT datename(weekday, '2004-10-15') --q回Q星期五
6. day(), month(),year() --可以与datepart对照一?/p>
select 当前日期=convert(varchar(10),getdate(),120)
,当前旉=convert(varchar(8),getdate(),114)
select datename(dw,'2004-10-15')
select 本年W多周=datename(week,'2004-10-15')
,今天是周?datename(weekday,'2004-10-15')
函数 | 参数/功能 |
GetDate( ) | q回pȝ目前的日期与旉 |
DateDiff (interval,date1,date2) | 以interval 指定的方式,q回date2 与date1两个日期之间的差?date2-date1 |
DateAdd (interval,number,date) | 以interval指定的方式,加上number之后的日?/td> |
DatePart (interval,date) | q回日期date中,interval指定部分所对应的整数?/td> |
DateName (interval,date) | q回日期date中,interval指定部分所对应的字W串名称 |
参数 interval的设定值如下:
?/b> | ~?写(Sql ServerQ?/b> | Access ?ASP | 说明 |
Year | Yy | yyyy | q?1753 ~ 9999 |
Quarter | q | ?1 ~ 4 | |
Month | Mm | m | ? ~ 12 |
Day of year | Dy | y | 一q的日数,一q中的第几日 1-366 |
Day | Dd | d | 日,1-31 |
Weekday | Dw | w | 一周的日数Q一周中的第几日 1-7 |
Week | Wk | ww | 周,一q中的第几周 0 ~ 51 |
Hour | Hh | h | ? ~ 23 |
Minute | Mi | n | 分钟0 ~ 59 |
Second | Ss | s | U?0 ~ 59 |
Millisecond | Ms | - | 毫秒 0 ~ 999 |
access ?asp 中用date()和now()取得pȝ日期旉Q其中DateDiff,DateAdd,DatePart也同是能用于Access和asp中,q些函数的用法也cM
举例Q?br />1.GetDate() 用于sql server :select GetDate()