2016-08-26 16 views
0

ISBNを10桁から13桁に変換する必要があります。私は試してみましたが、正しい結果を得られませんでした。これは私が試したコードであり、正しい結果を与えていません。oracle ISBN10を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

あなたは何を期待しますか?例を挙げてください。 –

+0

ロジックを分析するのが難しい。あなたの言葉をあなたの言葉で書くことができる、それを一度実装することができるかもしれない – XING

+1

何が**正しい**何ですか?私はあなたのコードから推測する必要はないと思っていますが、これは正しい結果をもたらさない**と言っています。それで、どうやって?または** ISBN10をISBN13に変換することが何を意味するのか**を知ることが期待されていますか? – mathguy

答えて

0

私は正しい結果を持っています。

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

私は次のコードは自明であるべきだと思います。詳細は、Wikipediaのリンクを参照してください。

-- 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; 
/

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

「0-596-51446-x」のチェック桁は「8」で、「0-30-640615-x」のチェック桁は2でなければなりません。しかし、それは私が推測する問題には関係ありません。 –

+1

@DavidAldridgeレビューと私のために欠落している小切手の桁を掘り出してくれてありがとう。私は問題に関連していないので、/ google'emを計算するのは面倒ではありませんでした。これらのISBNの書籍は、このSOタグには関係があります:) – user272735

関連する問題