2014-11-08 169 views
0
ALTER TABLE info 
ADD CONSTRAINT uppercase 
CHECK (password = UPPER(substr(password, 1 ,1))); 

我很好奇为什么我的约束不起作用?第一次试图写一个约束,所以在这里忍受。SQL约束的第一个字母是大写

+1

明显的问题是,您将1个字符与整个字符串进行比较,这只适用于单个字符的字符串。什么RDBMS?你使用哪些大小写敏感和排序选项?你为什么以纯文本形式存储密码并强制以密码开头? – 2014-11-08 21:24:53

+1

无关紧要,但如果密码的第一个字母对您来说很重要,那么您似乎没有加密或散列密码。你应该。最好散列(和腌制)你的密码。 – 2014-11-08 21:31:41

+0

我想通了。但这是一个很好的问题,并且会记住永远不会存储密码。 – user3716005 2014-11-08 21:36:19

回答

2

如果您使用的是MySQL,它不起作用,因为约束没有被强制执行。在其他一些数据库中,默认排序规则=的大写和小写相同。而且,无论默认排序规则如何,它可能会针对您的数据库进行更改。你可以很容易地做到这一点

方式一:

ALTER TABLE info 
    ADD CONSTRAINT uppercase CHECK (ASCII(LEFT(password, 1)) BETWEEN ASCII('A') and ASCII('Z')); 

这就是说,在大多数情况下,密码应被存储在数据库中的加密方式。这非常危险。您可以在数据库层加密密码。我认为在客户端层进行加密更好,所以自由文本密码甚至不会在网络上进行加密。

+0

“*在大多数其他数据库中,=的默认排序规则为大写和小写相同。*” - 这不正确(并且违反SQL标准)。 (至少)Oracle,Postgres,DB2,Firebird,Informix,Vertica,Teradata,Greenplum,HSQLDB和Apache Derby字符串比较区分大小写 – 2014-11-08 21:36:27

+0

感谢您的回答。我把整个结果比作一封没有意义的信。 – user3716005 2014-11-08 21:36:47

+1

+1。虽然在双方都有一个非常有效的加密情况,所以双方都看不到原始形式和最终形式。 @ user3716005只要在创建密码和登录匹配时执行相同的例程,就不会产生任何匹配问题(Gordon暗示它不会)。对OP的道歉,但对特定位置的限制是愚蠢的,因为每个用户都知道该特定位置有这种限制(最好是在字符串中需要大写字母)。虽然大多数用户会很懒,但攻击者不知道该字符串是否是String,sTring,strinG等。 – 2014-11-08 21:39:00

相关问题