Background Image

FORUM

조회 수 16616 추천 수 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
번호 제목 글쓴이 날짜 조회 수
공지 SQLGate for CUBRID 영구 무료 라이선스 제공 file admin 2020.04.09 4442
1047 MSSQL같이 레코드 복사는 안 되나요? 1 하늘나무 2014.03.28 10491
1046 mysql로 마이그레이션하는방법좀.. 1 썬해바라기 2009.12.14 10493
1045 systimestamp 함수로 현재시간을 불러올 경우 에러가 발생합니다. 1 노랑배 2011.01.28 10495
1044 마이그레이션 툴문의 3 webdoors 2010.03.23 10497
1043 cubrid 2008 R 2.1에서 2.2 버전으로 업그레이드 문의 2 file 종이 2010.06.04 10498
1042 database 시동이 안되요 1 2 나상숙 2009.04.04 10498
1041 broker error 8 쪼로롱 2014.02.26 10501
1040 질의 편집기로 부질의 유도테이블 쿼리실행에 대해 2 Chans 2009.09.17 10503
1039 9.1 가져오기 / 내보내기 2 bellstar 2014.05.13 10506
1038 IF문 관련 질문입니다. 1 뿌잉 2014.02.18 10516
1037 데이타 올리기로 데이타 삽입후 db_serial 변경 문의 1 초보 2010.04.08 10521
1036 [해결됨] 3.0 -> 3.1 이전중에 문제가 발생해서 현재 업무 마비상태 입니다. 11 file reerror 2011.03.25 10530
1035 컬럼 데이터타입 수정 문의 2 지렸당께 2011.12.05 10537
1034 기본값 설정 문의 3 칸의후계자 2009.09.16 10537
1033 날짜사이 데이터 1 ES 2010.11.12 10543
1032 테이블 복구 1 mydream 2010.02.26 10544
1031 LEFT 함수 문의 1 유니콘 2010.08.12 10547
1030 다름이아니라 PHP 모듈관련 1 ghkdldjfld 2010.04.03 10556
1029 트랜잭션의 상세정보를 확인할수 있는 방법이 있나요? 1 김현성 2011.06.01 10559
1028 커넥션 유지 관련 2 구름마음 2013.07.05 10564
Board Pagination Prev 1 ... 143 144 145 146 147 148 149 150 151 152 ... 200 Next
/ 200

Contact Cubrid

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