0

So here is the question: Write code to take in an id and determine if the check digit is correct

UPDATED CODE:

    Set SERVEROUTPUT ON
 DECLARE
      val_num NUMBER := '&user_input';
      holder NUMBER := 0;
      y NUMBER := 0;
      conv_string VARCHAR2(20);
   BEGIN
     conv_string := to_char(val_num*10);
     for x in 1..length(conv_string) loop
       y := to_number(substr(conv_string, -x, 1));
       if mod(x,2) = 0 then
         y := y * 2;
        if y > 9 then
         y := y - 9;
        end if;
       end if;
      holder := holder + y;
    end loop;
    dbms_output.put_line ('Check is '||(11-Mod(holder, 11)));
 END luhn;
   /
 SET SERVEROUTPUT ON

The return is:

SQL> @ loop
Enter value for user_input: 036532
old   2:       val_num NUMBER := '&user_input';
new   2:       val_num NUMBER := '036532';
Check is 2

It should be 6

Jeff Mercier
  • 39
  • 1
  • 6

2 Answers2

3

Before actual execution

SET SERVEROUTPUT ON

to enable SQL*Plus to fetch database output buffer.

Here is solution: https://community.oracle.com/thread/837639?start=0&tstart=0

Husqvik
  • 5,669
  • 1
  • 19
  • 29
  • 770100020011360 should check as 6 but it is checking as 24 – Jeff Mercier Dec 09 '15 at 03:21
  • Then your implementation has some flaw. Describe the algorithm for calculating the check digit – Husqvik Dec 09 '15 at 03:23
  • -Assign weights to each digit of the id #. The weights in MOD11 are from 2 through a maximum of 10 beginning with the low order position in the field. -Each digit in the id # is multiplied by its weight -The results of the multiplication are added together -This product is divided by the modulus number 11 -The remainder is subtracted from the modulus number 11 giving the -check digit – Jeff Mercier Dec 09 '15 at 03:27
  • 1
    @JeffMercier You should update the question with your description of the check digit algorithm. How do you expect anyone to tell you if your code is wrong if you don't tell them what the algorithm is? – WW. Dec 09 '15 at 03:35
  • @Husqvik its luhn algorithm – Jeff Mercier Dec 09 '15 at 04:29
  • 1
    The link provided by husqvik has the answer in it, 2 things need updating in your implimentation 1) the first line after the begin needs to be 'conv_string := to_char(val_num*10)' and 2) the dbms_output needs to be 'dbms_output.put_line('Check is ' || to_char(10-Mod(holder, 10)));' – Shaun Peterson Dec 09 '15 at 05:06
  • I saw the link but it's in a function not a straight up plsql that's why it was throwing me off, you can't do a return in my code since it is not a function. – Jeff Mercier Dec 09 '15 at 16:21
  • @ShaunPeterson with your code that was implemented it is still wrong – Jeff Mercier Dec 09 '15 at 21:03
0

There are lots of different variations of the luhn algorithm, so looking at these implementations and your (I think incomplete) description in the comments I think this may be fairly close to what you are looking for, and gives the correct checksum for 036532 as per your initial question.

Hope it is helpfull

Set SERVEROUTPUT ON
 DECLARE
      val_num number := '036532';
      holder NUMBER := 0;
      y NUMBER := 0;
      conv_string VARCHAR2(20);
   BEGIN
     conv_string := to_char(val_num);
     FOR X IN 1..LENGTH(CONV_STRING) LOOP
       Y := TO_NUMBER(SUBSTR(CONV_STRING, -X, 1));
       IF ((X+1) > 10) THEN 
          Y := Y * 10;
       ELSE
          Y := Y * (X + 1);
       END IF;
       IF (Y >= 10) THEN 
          HOLDER := HOLDER + TO_NUMBER(substr(TO_CHAR(Y), 1, 1)) +  TO_NUMBER(substr(TO_CHAR(Y), 2, 1));
       ELSE
          HOLDER := HOLDER + Y;
       END IF;
     END LOOP;

         HOLDER :=  MOD(HOLDER, 11);
         Holder := 11 - mod(holder, 11);
     dbms_output.put_line ('Check is '|| holder);
 END luhn;
   /
 SET SERVEROUTPUT ON 
Shaun Peterson
  • 1,735
  • 1
  • 14
  • 19