Background Image

FORUM

조회 수 16551 추천 수 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 2003
2513 ADD AFTER, FIRST 명령어와 ALTER MODIFY, CHANGE 문제 1 무냉채 2017.03.01 9373
2512 ibatis에서 create문 생성 1 file kkong 2017.03.01 10022
2511 Cubrid FUNCTION 한글 깨짐 문제 3 file 록밥 2017.02.24 9593
2510 Cubrid FUNCTION 한글 깨짐 문제 1 록밥 2017.02.24 9674
2509 unloddb 실행 3 secret 초초초보 2017.02.22 11
2508 cubrid loaddb 문의 3 나무천사 2017.02.17 9822
2507 Release upgrade 문의 1 yscoma 2017.02.13 9125
2506 HA 이용시 데이터 일관성 관련 문의드립니다. 1 안산혀눙이 2017.02.10 9244
2505 Database 실행이 안됩니다. 1 secret 질의응답요청 2017.02.08 14
2504 큐브리드 매니저 9.3.6.0006 - INSERT/UPDATE 문 생성 시, NULL 오타 2 file 차오이 2017.02.03 11983
2503 Cannot communicate with the broker 오류 7 secret 금먼지 2017.02.03 41
2502 내보내기가 안되요. 1 file 봉보로봉봉 2017.02.03 11617
2501 최근 등록/수정 여부 추출 1 살려주세요 2017.02.01 11609
2500 /etc/rc3.d/S98cubrid 화일 좀 바꿔주세요 1 꽁꽁단무지 2017.01.25 12237
2499 큐브리드 10 버전 리스트 분할 문의 종이 2017.01.25 12975
2498 comment 기능 질문입니다. 1 Hnyy.J 2017.01.24 10091
2497 백업 후 insert 오류 1 봉보로봉봉 2017.01.23 15070
2496 큐브리드 매니저 마이그레이션 DB소유자 관련 질문입니다. 3 석현진 2017.01.19 15107
» 저장프로시저 관련 문의 사항입니다. 3 file reassasin 2017.01.18 16551
2494 mac cubrid 설치 및 사용 오류 1 양갱 2017.01.10 16038
Board Pagination Prev 1 ... 53 54 55 56 57 58 59 60 61 62 ... 183 Next
/ 183

Contact Cubrid

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