Background Image

FORUM

조회 수 16617 추천 수 0 댓글 3
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

* 질문 등록 시 다음의 내용을 꼭 기입하여 주세요.
OS
Window Server 2008 R2 Enterprise
CUBRID Ver.
CUBRID 9.3 (9.3.6.0002) (64bit release build for Windows_NT) (Feb 29 2016 11:07:39)
CUBRID TOOL Ver.
CUBRID Manager 9.3.6.005  (64bit)
응용 환경(API)
C# ADO .net

* CUBRID 응용 오류, SQL 오류 또는 SQL 튜닝 관련된 문의는 반드시 다음의 내용을 추가해 주세요. 비밀글이나 비밀 댓글도 가능합니다.
* 저희가 상황을 이해하고, 재현이 가능해야 알 수 있는 문제들이 많습니다. 가능한 정보/정황들을 부탁합니다.
에러 내용 및 재현 방법 재현 가능한 Source와 SQL
관련 테이블(인덱스, 키정보 포함) 정보 CUBRID 홈 디렉토리 아래 log 디렉토리 압축


-------------- 아래에 질문 사항을 기입해 주세요. ------------------------------------------------------------------------

안녕하세요

큐브리드 DB를 현재 잘 사용하고 있는 유저입니다.

일반적으로 추세가 오라클 DB를 사용하다가 점점 높아지는 가격으로인하여 큐브리드DB로 마이그레이션 시도를 진행하고 있는데요.

큐브리드 저장 프로시저 관련하여 문의 사항이 있어 다음과 같이 정리하였습니다.


오라클의 경우 프로시저를 사용할 경우 OUT 파라메터를 이용하여 다수의 결과 값을 리턴 받을 수 있습니다.

이와 유사하게 큐브리드DB에서도 아래와 같은 형태로 큐브리드 메니저의 질의 편집기를 통하여 다수의 결과 값을 리턴을 수 있는 것까지는 확인을 하였습니다.


---질의 편집기 ---- 

SELECT 1 INTO :N_RETURN;

SELECT '' INTO :V_RETURN;

SELECT '' INTO :C_RETURN1;

SELECT '' INTO :C_RETURN2;


CALL get_data2('10968','22', :N_RETURN, :V_RETURN, :C_RETURN1, :C_RETURN2);


SELECT :N_RETURN, :V_RETURN, :C_RETURN1,  :C_RETURN2;

---질의 편집기 ----


-- 결과 값 시작 --

1 0 complete <?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>

<ResultSet>

    <Table>

        <Row>

            <code>10968</code>

            <name>Falck Ismo Kalevi</name>

            <gender>M</gender>

            <nation_code>FIN</nation_code>

            <event>Archery</event>

        </Row>

    </Table>

</ResultSet>

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>

<ResultSet>

    <Table>

        <Row>

            <code>16727</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>&#54624;&#51064;&#54665;&#49324;</event>

        </Row>

        <Row>

            <code>16728</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16729</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16730</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16731</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16732</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16733</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16734</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16735</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16736</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16737</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16738</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16739</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16740</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16741</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

        <Row>

            <code>16742</code>

            <name>22</name>

            <gender>M</gender>

            <nation_code>ESP</nation_code>

            <event>Handball</event>

        </Row>

    </Table>

</ResultSet>

-- 결과 값 끝 --

문제는 질의편집기에서 프로시저의 다중 리턴이 정상적으로 이루어지는 것을 확인하였습니다.
문제는 C#의 ADO .NET 드라이버를 이용하여 아래와 같이 호출을 처리하고 있으나 java단은 nullpoint Exception이 발생하고 있습니다.

-- C# 코드 시작
            using (CUBRIDConnection conn = new CUBRIDConnection())
            {
                conn.ConnectionString = ConnectionString;
                conn.Open();

                string sql = "CALL get_data2(?,?,?,?,?,?)";
                using (CUBRIDCommand cmd = new CUBRIDCommand(sql, conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;

                    CUBRIDParameter p1 = new CUBRIDParameter("?p1", CUBRIDDataType.CCI_U_TYPE_VARNCHAR);
                    p1.Direction = ParameterDirection.Input;   // output
                    p1.Value = "16727";
                    cmd.Parameters.Add(p1);

                    CUBRIDParameter p2 = new CUBRIDParameter("?p2", CUBRIDDataType.CCI_U_TYPE_VARNCHAR);
                    p2.Direction = ParameterDirection.Input;   // output
                    p2.Value = "22";
                    cmd.Parameters.Add(p2);

                    CUBRIDParameter p3 = new CUBRIDParameter("?p3", CUBRIDDataType.CCI_U_TYPE_INT);
                    p3.Direction = ParameterDirection.Output;   // output
                    p3.Value = -1;
                    cmd.Parameters.Add(p3);

                    CUBRIDParameter p4 = new CUBRIDParameter("?p4", CUBRIDDataType.CCI_U_TYPE_VARNCHAR);
                    p4.Direction = ParameterDirection.Output;   // output
                    p4.Size = 1000;
                    cmd.Parameters.Add(p4);

                    CUBRIDParameter p5 = new CUBRIDParameter("?p5", CUBRIDDataType.CCI_U_TYPE_VARNCHAR);
                    p5.Direction = ParameterDirection.Output;   // output
                    p5.Size = 1000;
                    cmd.Parameters.Add(p5);

                    CUBRIDParameter p6 = new CUBRIDParameter("?p6", CUBRIDDataType.CCI_U_TYPE_VARNCHAR);
                    p6.Direction = ParameterDirection.Output;   // output
                    p6.Size = 1000;
                    cmd.Parameters.Add(p6);

                    cmd.ExecuteNonQuery();  // <-- java null point exception발생함.

                    Console.WriteLine("p1 = " + p1.Value);
                    Console.WriteLine("p2 = " + p2.Value);
                    Console.WriteLine("p3 = " + p3.Value);
                    Console.WriteLine("p4 = " + p4.Value);
                    Console.WriteLine("p5 = " + p5.Value);
                    Console.WriteLine("p6 = " + p6.Value);


                    Console.ReadKey();
                }


-- C# 코드 종료



-- Exception 내용

{"Stored procedure execute error: java.lang.NullPointerException"}

   위치: CUBRID.Data.CUBRIDClient.CUBRIDStream.Receive()

   위치: CUBRID.Data.CUBRIDClient.CUBRIDStream.RequestExecute(Int32 handle, CCIExecutionOption executionFlag, CUBRIDParameter[] parameters, Byte[] paramModes, Byte fetchFlag, Boolean autoCommit)

   위치: CUBRID.Data.CUBRIDClient.CUBRIDCommand.ExecuteInternal()

   위치: CUBRID.Data.CUBRIDClient.CUBRIDCommand.ExecuteNonQuery()

   위치: CubridTest.Program.Main(String[] args) 파일 D:

  • ?
    진우진 2017.01.19 03:11
    cmd.Parameters.Add(new CUBRIDParameter("?p1", DbType.String));
    cmd.Parameters["?p1"].Value = "ZZZ";

    파라미터 설정하는 부분을 위와 같이 변경하여 실행해보시기 바랍니다.

    프로시저의 다중 리턴은 불가합니다.
  • ?
    reassasin 2017.01.19 19:13

    우선 답변 감사합니다.

    기존의 코드에서 알려주신대로 처리한 결과 Exception부분은 해결이 된 것 같습니다.

    그리고 프로시저의 다중 리턴이 불가하다고 말씀하셨는데요. 일부 되는 것도 확인을 하였습니다.

    다만 리턴되어온 값들이 맞지않는 현상이 있습니다.

    관련하여 내용은 아래와 같습니다. 확인 부탁 드립니다.


    큐브리드단 프로시저 형태는 아래와 같습니다.

    -- 큐브리드 단 프로시져 정의

    CREATE PROCEDURE get_data2 (

    A_CODE STRING,

    A_NAME STRING,

    N_RETURN OUT INTEGER,

    V_RETURN OUT STRING,

    C_RETURN1 OUT STRING,

    C_RETURN2 OUT STRING

    )

    AS LANGUAGE JAVA NAME 'Athlete.GetData2(java.lang.String,java.lang.String,java.lang.Integer[],java.lang.String[],java.lang.String[],java.lang.String[])'


    그리고 java단 method는 아래와 같습니다.

    -- 자바단 Stored Procedure

    public class Athlete{

    public static void GetData2(String A_CODE,String A_NAME,

    Integer[] N_RETURN, String[] V_RETURN, String[] C_RETURN1, String[] C_RETURN2) throws SQLException {

    String sql = "";

    try {

    Class.forName("cubrid.jdbc.driver.CUBRIDDriver");

    Connection conn = DriverManager

    .getConnection("jdbc:cubrid:100.100.100.172:30000:demodb:::?charset=UTF-8");


    DocumentBuilderFactory factory = DocumentBuilderFactory

    .newInstance();

    DocumentBuilder builder = factory.newDocumentBuilder();

    Document doc = builder.newDocument();

    Element resultSetEle = doc.createElement("ResultSet");

    doc.appendChild(resultSetEle);


    sql = "select * from ATHLETE where CODE = " + A_CODE;

    PreparedStatement stmt = conn.prepareStatement(sql);

    ResultSet rs = stmt.executeQuery();

    AppendTable(doc, resultSetEle, rs);

    C_RETURN1[0] = getDocumentAsXml(doc);

    stmt.close();

    rs.close();

    factory = DocumentBuilderFactory

    .newInstance();

    builder = factory.newDocumentBuilder();

    doc = builder.newDocument();

    resultSetEle = doc.createElement("ResultSet");

    doc.appendChild(resultSetEle);


    sql = "select * from ATHLETE where NAME = '" + A_NAME + "'";

    stmt = conn.prepareStatement(sql);

    rs = stmt.executeQuery();

    AppendTable(doc, resultSetEle, rs);

    stmt.close();

    rs.close();

    conn.close();

    C_RETURN2[0] = getDocumentAsXml(doc);

    N_RETURN[0] = 0;

    V_RETURN[0] = "정상처리되었습니다.";

    } catch (Exception e) {

    N_RETURN[0] = 1;

    V_RETURN[0] = e.getMessage();

    C_RETURN1[0] = null;

    C_RETURN2[0] = null;

    }

    }

    }

    그리고 C#단의 코드는 아래와 같습니다.

    -- C#단 프로그램

                using (CUBRIDConnection conn = new CUBRIDConnection())

                {

                    conn.ConnectionString = ConnectionString;

                    conn.Open();


                    string sql = "CALL get_data2(?,?,?,?,?,?)";

                    using (CUBRIDCommand cmd = new CUBRIDCommand(sql, conn))

                    {

                        cmd.CommandType = CommandType.StoredProcedure;


                        cmd.Parameters.Add(new CUBRIDParameter("?p1", DbType.String));

                        cmd.Parameters["?p1"].Value = "16727";

                        cmd.Parameters["?p1"].Direction = ParameterDirection.Input;


                        cmd.Parameters.Add(new CUBRIDParameter("?p2", DbType.String));

                        cmd.Parameters["?p2"].Value = "22";

                        cmd.Parameters["?p2"].Direction = ParameterDirection.Input;


                        cmd.Parameters.Add(new CUBRIDParameter("?p3", DbType.String));

                        cmd.Parameters["?p3"].Value = "";

                        cmd.Parameters["?p3"].Direction = ParameterDirection.Output;


                        cmd.Parameters.Add(new CUBRIDParameter("?p4", DbType.String));

                        cmd.Parameters["?p4"].Value = "";

                        cmd.Parameters["?p4"].Direction = ParameterDirection.Output;


                        cmd.Parameters.Add(new CUBRIDParameter("?p5", DbType.String));

                        cmd.Parameters["?p5"].Value = "";

                        cmd.Parameters["?p5"].Direction = ParameterDirection.Output;


                        cmd.Parameters.Add(new CUBRIDParameter("?p6", DbType.String));

                        cmd.Parameters["?p6"].Value = "";

                        cmd.Parameters["?p6"].Direction = ParameterDirection.Output;


                        cmd.ExecuteNonQuery();


                        Console.WriteLine("p1 = " + cmd.Parameters["?p1"].Value);

                        Console.WriteLine("p2 = " + cmd.Parameters["?p2"].Value);

                        Console.WriteLine("p3 = " + cmd.Parameters["?p3"].Value);

                        Console.WriteLine("p4 = " + cmd.Parameters["?p4"].Value);

                        Console.WriteLine("p5 = " + cmd.Parameters["?p5"].Value);

                        Console.WriteLine("p6 = " + cmd.Parameters["?p6"].Value);


                        Console.ReadKey();

                    }

                }

            }


    실제로 출력된 값은 아래와 같습니다.

    -- 출력 결과

    p1 = 16727

    p2 = 22

    p3 =

    p4 =

    p5 = 0

    p6 = 정상처리되었습니다.


    C#단과 자바 프로시저 단의 파라메터 매칭이 아래와 같이 이루어 져야 정상인데요.

    -- 예상되는 정상적인 결과

    C#단    :     자바단

    p1   :      A_CODE

    p2      :      A_NAME

    p3      N_RETURN

    p4 V_RETURN

    p5 C_RETURN1

    p6 C_RETURN2


    -- 실제로 출력 결과값을 봤을때 매칭되

    C#단    :     자바단

    p1   :      A_CODE

    p2      :      A_NAME

    p3     

    p4

    p5 N_RETURN

    p6 V_RETURN


    실제로 출력 결과는 p3과 p4에 아무런 값이 할당되지 않은채로 p5와 p6에 각각 p3과 p4에 해당하는 결과 값이 출력됩니다.

    답변 주신대로 큐브리드 java stored procedure가 다중 결과 리턴을 지원하지 않는다면,

    아예 이와 같이 처리되지 않아야 하는 것이 맞을 듯 한데요.

    실제로는 결과가 리턴이 되고 있습니다.

    다만 실제 출력결과와 같이 순서가 밀려서 리턴되는 현상이 발생하고 있습니다.

    즉 C_RETURN1과 C_RETURN2 값이 제대로 리턴이 되지 않습니다.

    프로그래밍 상으로 잘못처리한 부분이 있는지 검토 부탁드립니다.




  • ?
    진우진 2017.01.20 00:56

    프로시저에서 다중 리턴을 지원하지 않는다는 것은 프로시저의 처리 결과로써 여러 row를 리턴하는 것이 불가능 하다는 것을 말하는 것으로,

    여러개의 파라미터로 각각의 값을 받아내는 것은 가능합니다. 서로 의미의 혼동이 있었던 것 같습니다. 


    파라미터 순서 문제는 ADO.NET 소스 내에서

    p1과 p2의 Direction을 Input에서 InputOutput 으로 변경하면 정상적인 순서로 출력됩니다.


List of Articles
번호 제목 글쓴이 날짜 조회 수
공지 CUBRID 사용자를 위한 DBeaver 도구 출시 안내 admin 2024.04.23 61
공지 SQLGate for CUBRID 영구 무료 라이선스 제공 file admin 2020.04.09 4464
957 재설치가 안되요 1 냐우루 2012.11.28 6074
956 저 혹시 개발에 있는 데이터를 운영에 바로 등록할 수 있는 방법이 없나요??? 5 secret 처음처럼초보 2016.08.31 8
955 저장 프로스저에 있는 함수 상세보기 문의입니다. 1 대출인생30년 2023.06.12 82
954 저장 프로시저 사용시 커넥션 관련 4 고늬 2018.04.11 394
953 저장 프로시저 작성법 1 webdoors 2010.03.14 16379
952 저장 프로시저에서 JDBC 연결이 안되는 것 같습니다. 2 animan10 2017.03.10 9784
951 저장 프로시져 질문 3 file 이석희 2009.03.12 16480
950 저장 함수 호출 오류 3 keem 2021.08.12 503
949 저장프로시저 샘플 테스트 에러 Invalid call: it can not return ResultSet. 5 흔색늑대 2022.10.21 126
948 저장프로시저 관련 문의 2 toy2508 2014.11.04 8200
» 저장프로시저 관련 문의 사항입니다. 3 file reassasin 2017.01.18 16617
946 저장프로시저 실행관련 문의 4 f0081 2023.11.08 139
945 저장프로시저 함수-loadjava 3 쪼로롱 2010.02.23 15674
944 저장프로시저(function) 오류 문제입니다. 1 yoon 2010.03.29 10732
943 저장프로시저나 함수 질문 1 난래리 2015.11.13 5100
942 저장함수 관련질문 2 hscho 2016.09.02 12939
941 저장함수 문제요.. 1 owlowl 2016.08.24 12657
940 저장함수에 대하여 1 보리빵 2010.03.04 9854
939 전송 연결 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다 1 바람바람 2013.04.12 20697
938 전송 연결 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다에서 데이터를 읽을 수 없습니다. 2 바람바람 2013.03.29 42890
Board Pagination Prev 1 ... 148 149 150 151 152 153 154 155 156 157 ... 200 Next
/ 200

Contact Cubrid

대표전화 070-4077-2110 / 기술문의 070-4077-2113 / 영업문의 070-4077-2112 / Email. contact_at_cubrid.com
Contact Sales