Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何检查DB列中的值是否为BSN(荷兰SSN)_Sql_Oracle - Fatal编程技术网

Sql 如何检查DB列中的值是否为BSN(荷兰SSN)

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

我正在寻找一种方法,使您能够判断列中的值是否为有效的BSN值。BSN(荷兰SSN)必须符合某种“11测试”。请注意,这与银行账户不同。查看详细信息

我想要返回的是一个零或一,表示我的BSN是否有效(=1)或无效(=0)。目前它存储为一个数字

我试着对此做一个SQL语句。我从以下行动开始:

  • 首先,我只想要有实际值且跳过(null)值的行:

  • 之后,我希望我的BSN是一个VARCHAR2

    SELECT TO_CHAR(D_BSN) FROM EMPLOYEE WHERE D_BSN IS NOT NULL;
    
  • 现在,我希望我的BSN始终具有相同的长度:

    SELECT DECODE(LENGTH(TO_CHAR(D_BSN)),8, '0' || D_BSN, D_BSN)
      FROM EMPLOYEE 
     WHERE D_BSN IS NOT NULL;
    
  • 现在,如果我的长度不是9,我有一个无效字段,因此“退出”为0

    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;
    
  • 此时,我发现我的SQL语句变得不可读。也因为我还有很长的路要走。我必须选择每个数字,乘以它的位置,求和结果,除以11,看看mod是否等于BSN的最后一个数字。这在编程语言中很容易,所以为什么不把它放在函数中呢。所以我可以这样使用它:

    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