使用Oracle数据库在SQL中使用数字检查最小精度的最佳方法是什么?
CreditCardNumber NUMBER(16) NOT NULL
CHECK (CreditCardNumber LIKE '________________')
或
CreditCardNumber NUMBER(16) NOT NULL
CHECK (REGEXP_LIKE(CreditCardNumber, '^\d{16}'))
我理解这是演示级别检查,但我听说在数据库级别上避免不合逻辑的数据仍然是一种很好的做法。
答案 0 :(得分:4)
您的所有功能都无法正常工作,因为您最终会将隐式数字转换为字符串转换。失去领先的零。也许这不是特定情况下的问题,假设信用卡号码永远不会以前导零开始(并且 ?< - >根据ISO/IEC 7812,前导号码可以< / em>在某些角落案件中成为0
。
但是,请注意,您在使用NUMBER
类型时没有任何好处,因为您永远不会对信用卡“号码”进行计算。因此,对于那种数据(信用卡“号码,电话号码”,邮政编码......),我强烈建议您使用字符类型(VARCHAR2
或CHAR
相反,并且至少使用适当的正则表达式进行检查,而不仅仅是数字是字符串的一部分。尽管@Allan在他的回答中建议验证校验和会更好。
此外,即使16位数是最常见的情况,bank card numbers也是可变长度 - 从12到19位数(根据http://www.watersprings.org/pub/id/draft-eastlake-card-map-08.txt,因为我无法访问ISO官方文件)。
最后,关于信用卡号码,您必须记住,根据您当地的规定,您不一定能够以未加密的方式存储它们。
答案 1 :(得分:1)
NUMBER(16)
只会允许整数(例如,如果您尝试插入&#39; 10.1&#39;,它将会转到&#39; 10&#39;)。
请记住,信用卡号码不总是16位数 - 美国运通使用15位。
您在存储NUMBER类型的信用卡号码时获得的仅收益是存储空间。由于数字以9位到4位的比例打包,因此8个字节将存储16位数。但是,与数据的每次交互都需要对文本进行类型转换,因此您必须权衡存储,处理和编码的难度。
答案 2 :(得分:1)
验证值足够宽的明显方法是以数字方式检查值:
CreditCardNumber NUMBER(16) NOT NULL
CHECK (CreditCardNumber >= 1000000000000000)
但是,正如@BenGrimm指出的那样,这可能对所有信用卡号都无效。
验证每个提供商的卡长度的一种方法是使用您接受的每个提供商的查找表以及卡号的长度。同样,您必须使用触发器来检查,但它可以让您验证长度是否恰当是正确的。
更好的验证可能是在函数中实现Luhn algorithm并使用它通过触发器验证列值。
最后,重申Sylvain Leroux指出的内容,这应该都是学术性的。您不应该以明文形式存储信用卡号码,甚至可能在法律上或合同上无法这样做。
答案 3 :(得分:0)
您可能会使用上限(log10(数字))= 16.我认为对于信用卡号码,有更好的方法可以检查。