2016-08-26 1 views
0

Ich muss ISBN von 10 Ziffern in 13 Ziffern konvertieren. Ich habe versucht, aber nicht korrektes Ergebnis zu erhalten. Dies ist der Code, den ich versucht habe und es gibt kein korrektes Ergebnis.Orakel Konvertieren von ISBN10 zu ISBN13

Create or replace FUNCTION F_ISBN_CONV_13 (ISBN_10 IN VARCHAR2) RETURN VARCHAR2 
    AS 
     V_ISBN_13 VARCHAR2(13); 
    BEGIN 
     SELECT 
     CASE WHEN LENGTH(ISBN_10) = 10 THEN 

      CASE WHEN SUBSTR(ISBN_10,1,3) = '801' THEN 
       '201' || 
       SUBSTR(ISBN_10,1,9) || 
       SUBSTR(
        (
         10 - 
         SUBSTR(
          (
           (
            2 + 
            1 + 
            SUBSTR(ISBN_10,2,1) + 
            SUBSTR(ISBN_10,4,1) + 
            SUBSTR(ISBN_10,6,1) + 
            SUBSTR(ISBN_10,8,1) 
           ) + 
           (
            (
             0 + 
             SUBSTR(ISBN_10,1,1) + 
             SUBSTR(ISBN_10,3,1) + 
             SUBSTR(ISBN_10,5,1) + 
             SUBSTR(ISBN_10,7,1) + 
             SUBSTR(ISBN_10,9,1) 
            ) 
           ) * 3 
          ) 
          ,-1 
          ,1 
         ) 
        ) 
        ,-1 
        ,1 
       ) 
      ELSE 
       '978' || 
       SUBSTR(ISBN_10,1,9) || 
       SUBSTR(
        (
         10- 
         SUBSTR(
          (
           (
            9 + 
            8 + 
            SUBSTR(ISBN_10,2,1) + 
            SUBSTR(ISBN_10,4,1) + 
            SUBSTR(ISBN_10,6,1) + 
            SUBSTR(ISBN_10,8,1) 
           ) + 
           (
            (
             7 + 
             SUBSTR(ISBN_10,1,1) + 
             SUBSTR(ISBN_10,3,1) + 
             SUBSTR(ISBN_10,5,1) + 
             SUBSTR(ISBN_10,7,1) + 
             SUBSTR(ISBN_10,9,1) 
            ) 
           ) * 3 
          ) 
          ,1 
          ,1 
         ) 
        ) 
        ,-1 
        ,1 
       ) 
      END 
     ELSE 
      ISBN_10 
     END INTO V_ISBN_13 
    FROM 
     DUAL; 

    RETURN V_ISBN_13; 
EXCEPTION 
    --<code> 
END F_ISBN_CONV_13; 
+1

Was bekommen Sie und was erwarten Sie? Bitte geben Sie ein Beispiel an. –

+0

Zu schwer, um Ihre Logik zu analysieren. Kann sein, wenn Sie in Ihre Logik schreiben können, einmal kann es implementieren – XING

+1

Was ** ist ** das richtige Ergebnis? Ich nehme an, wir sind nicht verpflichtet, daraus abzuleiten, dass Ihr Code ** nicht ** das korrekte Ergebnis liefert. Also, wie sonst? Oder sollen wir ** wissen, was es bedeutet, ISBN10 zu ISBN13 zu konvertieren? – mathguy

Antwort

0

ich das richtige Ergebnis bekommen haben.

Create or replace FUNCTION F_ISBN_CONV_13 (ISBN_10 IN VARCHAR2) RETURN VARCHAR2 
    AS 
     V_ISBN_13 VARCHAR2(13); 
    BEGIN 
     SELECT 
     CASE WHEN LENGTH(ISBN_10) = 10 THEN 

      CASE WHEN SUBSTR(ISBN_10,1,3) = '801' THEN 
       '201' || 
       SUBSTR(ISBN_10,1,9) || 
       SUBSTR(
        (
         10 - 
         SUBSTR(
          (
           (
            2 + 
            1 + 
            SUBSTR(ISBN_10,2,1) + 
            SUBSTR(ISBN_10,4,1) + 
            SUBSTR(ISBN_10,6,1) + 
            SUBSTR(ISBN_10,8,1) 
           ) + 
           (
            (
             0 + 
             SUBSTR(ISBN_10,1,1) + 
             SUBSTR(ISBN_10,3,1) + 
             SUBSTR(ISBN_10,5,1) + 
             SUBSTR(ISBN_10,7,1) + 
             SUBSTR(ISBN_10,9,1) 
            ) 
           ) * 3 
          ) 
          ,-1 
          ,1 
         ) 
        ) 
        ,-1 
        ,1 
       ) 
      ELSE 
       '978' || 
       SUBSTR(ISBN_10,1,9) || 
       SUBSTR(
        (
         10- 
         SUBSTR(
          (
           (
            9 + 
            8 + 
            SUBSTR(ISBN_10,2,1) + 
            SUBSTR(ISBN_10,4,1) + 
            SUBSTR(ISBN_10,6,1) + 
            SUBSTR(ISBN_10,8,1) 
           ) + 
           (
            (
             7 + 
             SUBSTR(ISBN_10,1,1) + 
             SUBSTR(ISBN_10,3,1) + 
             SUBSTR(ISBN_10,5,1) + 
             SUBSTR(ISBN_10,7,1) + 
             SUBSTR(ISBN_10,9,1) 
            ) 
           ) * 3 
          ) 
          ,-1  -- Need to change here from '1' to '-1' 
          ,1 
         ) 
        ) 
        ,-1 
        ,1 
       ) 
      END 
     ELSE 
      ISBN_10 
     END INTO V_ISBN_13 
    FROM 
     DUAL; 

    RETURN V_ISBN_13; 
EXCEPTION 
    --<code> 
END F_ISBN_CONV_13; 
1

Ich denke, der folgende Code sollte selbsterklärend sein. Für Details siehe die Wikipedia-Links.

-- https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-10_to_ISBN-13_conversion 
create or replace function isbn10_to_13(p_isbn10 in varchar2) 
return varchar2 is 
    v_isbn10_digits constant varchar2(9) := substr(replace(p_isbn10, '-', ''), 1, 9); 
    v_isbn13 varchar2(17) := '978-' || substr(p_isbn10, 1, length(p_isbn10) - 1); 
    v_checkdigit number; 
begin 
    -- https://en.wikipedia.org/wiki/International_Standard_Book_Number#ISBN-13_check_digit_calculation 
    v_checkdigit := 
     (1 * 9) 
    + (3 * 7) 
    + (1 * 8) 
    + (3 * to_number(substr(v_isbn10_digits, 1, 1))) 
    + (1 * to_number(substr(v_isbn10_digits, 2, 1))) 
    + (3 * to_number(substr(v_isbn10_digits, 3, 1))) 
    + (1 * to_number(substr(v_isbn10_digits, 4, 1))) 
    + (3 * to_number(substr(v_isbn10_digits, 5, 1))) 
    + (1 * to_number(substr(v_isbn10_digits, 6, 1))) 
    + (3 * to_number(substr(v_isbn10_digits, 7, 1))) 
    + (1 * to_number(substr(v_isbn10_digits, 8, 1))) 
    + (3 * to_number(substr(v_isbn10_digits, 9, 1))) 
    ; 
    v_checkdigit := 10 - mod(v_checkdigit, 10); 

    if v_checkdigit = 10 
    then 
    v_checkdigit := 0; 
    end if; 

    return v_isbn13 || v_checkdigit; 
end; 
/

Beispiel

col isbn10 for a13 
col isbn13 for a17 

with isbn10(i10) as (
    select '0-30-640615-x' from dual union all 
    select '0-07-223065-7' from dual union all 
    select '0-596-51446-x' from dual 
) 
select isbn10.i10 as isbn10, isbn10_to_13(isbn10.i10) as isbn13 
from isbn10; 

ISBN10  ISBN13 
------------- ----------------- 
0-30-640615-x 978-0-30-640615-7 
0-07-223065-7 978-0-07-223065-9 
0-596-51446-x 978-0-596-51446-4 
+1

Sieht gut aus, obwohl die Prüfziffer auf "0-596-51446-x" sollte "8" sein und auf "0-30-640615-x" sollte es 2 sein. Nicht relevant für das Problem, denke ich. –

+1

@DavidAldridge Danke für die Überprüfung und Ausgrabung der fehlenden Prüfziffern für mich. Ich habe mich nicht damit beschäftigt, Google zu berechnen, da sie für das Problem nicht relevant sind. Die Bücher mit diesen ISBN sind eher relevant für dieses SO-Tag :) – user272735