Sql 如何检查DB列中的值是否为BSN(荷兰SSN)
我正在寻找一种方法,使您能够判断列中的值是否为有效的BSN值。BSN(荷兰SSN)必须符合某种“11测试”。请注意,这与银行账户不同。查看详细信息 我想要返回的是一个零或一,表示我的BSN是否有效(=1)或无效(=0)。目前它存储为一个数字 我试着对此做一个SQL语句。我从以下行动开始:Sql 如何检查DB列中的值是否为BSN(荷兰SSN),sql,oracle,Sql,Oracle,我正在寻找一种方法,使您能够判断列中的值是否为有效的BSN值。BSN(荷兰SSN)必须符合某种“11测试”。请注意,这与银行账户不同。查看详细信息 我想要返回的是一个零或一,表示我的BSN是否有效(=1)或无效(=0)。目前它存储为一个数字 我试着对此做一个SQL语句。我从以下行动开始: 首先,我只想要有实际值且跳过(null)值的行: 之后,我希望我的BSN是一个VARCHAR2 SELECT TO_CHAR(D_BSN) FROM EMPLOYEE WHERE D_BSN IS NOT N
SELECT TO_CHAR(D_BSN) FROM EMPLOYEE WHERE D_BSN IS NOT NULL;
SELECT DECODE(LENGTH(TO_CHAR(D_BSN)),8, '0' || D_BSN, D_BSN)
FROM EMPLOYEE
WHERE D_BSN IS NOT NULL;
SELECT
DECODE(
LENGTH(DECODE(LENGTH(TO_CHAR(D_BSN)),8, '0' || D_BSN, D_BSN)), 9,
DECODE(LENGTH(TO_CHAR(D_BSN)),8, '0' || D_BSN, D_BSN), 0)
FROM MW_DOCUMENTS
WHERE D_BSN IS NOT NULL;
SELECT * FROM EMPLOYEE WHERE IS_BSN(D_BSN) = 0
获取所有无效的BSN。看看我的答案
更新:(添加了函数的代码)
以下是我的函数,返回一个零或一个1,指示有效或无效的BSN:
create or replace FUNCTION is_bsn(num_in NUMBER) RETURN NUMBER IS
-- Yes is BSN = True == 1
-- NO not BSN = False == 0
checkValue NUMBER := -1;
factor NUMBER := 9;
result NUMBER := 0;
outcome NUMBER := 0;
bsn VARCHAR2(9);
BEGIN
bsn := to_char(num_in);
-- Check if length is 8 if so add zero in front
IF LENGTH(bsn) = 8 THEN
bsn := '0' || bsn;
END IF;
-- Now length should be 9
IF LENGTH(bsn) <> 9 THEN
RETURN 0;
END IF;
checkValue := TO_NUMBER(SUBSTR(bsn, 9, 1));
FOR Lcntr IN 1..8
LOOP
result := result + TO_NUMBER(SUBSTR(bsn, Lcntr, 1)) * factor;
factor := factor - 1;
END LOOP;
outcome := result mod 11;
if outcome = checkValue then
return 1;
ELSE
return 0;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN 'FALSE';
END is_bsn;
create或replace函数为\u bsn(num\u in NUMBER)返回号为
--是BSN=True==1
--否不是BSN=False==0
校验值编号:=-1;
因子数:=9;
结果编号:=0;
结果数:=0;
bsn VARCHAR2(9);
开始
bsn:=到字符(num\u in);
--检查长度是否为8,如果是,则在前面加零
如果长度(bsn)=8,则
bsn:=“0”| | bsn;
如果结束;
--现在长度应该是9
如果长度(bsn)为9,则
返回0;
如果结束;
校验值:=TO_数(SUBSTR(bsn,9,1));
对于1..8中的Lcntr
环
结果:=结果+TO_编号(SUBSTR(bsn,Lcntr,1))*系数;
系数:=系数-1;
端环;
结果:=结果mod 11;
如果结果=检查值,则
返回1;
其他的
返回0;
如果结束;
例外
当其他人
返回“FALSE”;
结束是_bsn;
更新:
由于Wildplasser的答案是针对Postgress的,而最初的问题是针对Oracle的,因此我将他的答案转换为针对Oracle的:
create or replace FUNCTION is_bsn2(inBsn in NUMBER) RETURN NUMBER IS
-- Yes is BSN = True = 0
-- NO not BSN = False => 1
val NUMBER;
mul NUMBER;
bsn NUMBER := inBsn;
BEGIN
val := 11 - (bsn mod 10); -- the check digit
mul := 1;
WHILE (bsn > 0) loop
bsn := FLOOR (bsn / 10);
mul := mul + 1;
val := val + (bsn mod 10) * mul;
END LOOP;
IF (mul < 9) THEN
RETURN 13;
END IF; -- too short
RETURN val mod 11;
END;
create或replace函数为_bsn2(inBsn in NUMBER)返回号为
--是,BSN=True=0
--否非BSN=False=>1
val编号;
mul数;
bsn编号:=inBsn;
开始
val:=11-(bsn模块10);--校验位
mul:=1;
WHILE(bsn>0)循环
bsn:=楼层(bsn/10);
mul:=mul+1;
val:=val+(bsn模块10)*mul;
端环;
如果(mul<9),则
返回13;
如果结束;——太短
返回val mod 11;
终止
请注意,我将其重命名为is_bsn2,结果为>0表示不是有效的bsn。我看不出一个比另一个有多大的性能提升,但我还没有对它进行广泛的测试。这一切都可以在一个循环中完成,无需转换为字符
- 此版本接受整数参数。(9位十进制数应适合32位有符号整数)
- 成功时返回0,否则返回>0(这对我来说更有意义)
- 不需要处理异常,因为不存在可能的异常
- 这是为博士后准备的,但差别应该很小
创建函数bsn\u无效(bsn INTEGER)返回整数
像
$func$
声明
val整数;
多整数;
开始
val:=11-(bsn%10);--校验位
mul:=1;
while(bsn>0)循环
bsn:=(bsn/10);
mul:=mul+1;
val:=val+(bsn%10)*mul;
端环;
如果(mul<9),则返回13;如果结束;——太短
返回值%11;
终止
$func$语言plpgsql
;
--测试它::
选择bsn_无效(123456782);
选择bsn_无效(111222333);
选择bsn_无效(23456784);--假设一个前导零
选择bsn_无效(1234567);--太短
数据类型是什么?看起来它可能是一个数字,然后你把它连接起来。你到底想要什么?你要求一个函数,然后你发布一个关于你自己问题的答案和一个工作函数。我真的在这里迷路了。好吧,你的问题是什么?您已经发布了一些需求和一些代码,但没有指出代码可能存在哪些问题。请编辑您的问题,并告诉我们您的代码存在哪些问题-例如编译错误、错误结果等-也许有人可以提供帮助。如果你得到了错误的结果,请举例说明。谢谢。是的,这是一个号码。我改变了最初的问题,使之更清楚。在看到wildplasser的答案之前,我起初认为使用字符串会更容易,因此转换为字符串。使用数字作为数据类型的目的是什么。在我看来,整数在这里已经足够好了。(更好)
create or replace FUNCTION is_bsn2(inBsn in NUMBER) RETURN NUMBER IS
-- Yes is BSN = True = 0
-- NO not BSN = False => 1
val NUMBER;
mul NUMBER;
bsn NUMBER := inBsn;
BEGIN
val := 11 - (bsn mod 10); -- the check digit
mul := 1;
WHILE (bsn > 0) loop
bsn := FLOOR (bsn / 10);
mul := mul + 1;
val := val + (bsn mod 10) * mul;
END LOOP;
IF (mul < 9) THEN
RETURN 13;
END IF; -- too short
RETURN val mod 11;
END;
CREATE function bsn_invalid(bsn INTEGER) RETURNS INTEGER
AS
$func$
DECLARE
val INTEGER;
mul INTEGER;
BEGIN
val := 11- (bsn % 10); -- the check digit
mul := 1;
while (bsn > 0) loop
bsn := (bsn / 10);
mul := mul + 1;
val := val + (bsn%10)*mul;
end loop;
if (mul < 9) then return 13; END IF; -- too short
return val % 11;
END
$func$ LANGUAGE plpgsql
;
-- test it::
SELECT bsn_invalid( 123456782);
SELECT bsn_invalid( 111222333 );
SELECT bsn_invalid( 23456784); -- assume a leading zero
SELECT bsn_invalid( 1234567); -- too short