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
번호 제목 글쓴이 날짜 조회 수
공지 CUBRID 사용자를 위한 DBeaver 도구 출시 안내 admin 2024.04.23 47
공지 SQLGate for CUBRID 영구 무료 라이선스 제공 file admin 2020.04.09 4458
2934 select 시 한글 깨짐 문의 입니다. 1 닐릴리 2019.02.11 1178
2933 loadjava 실행시 에러 발생합니다. 1 지구인다 2019.01.31 645
2932 cubrid.conf 에 'oracle_style_empty_string=yes' 설정 후, 매니저 내 테이블 목록이 시스템 테이블만 보입니다. 4 shuaiT80 2019.01.31 278
2931 큐브리드 마이그레이션툴 사용시 권한질문입니다. 1 bjosbkjx 2019.01.31 208
2930 다중 REPLACE에 관한 질문입니다 2 위니텍 2019.01.30 2282
2929 다중 REPLACE에 관한 질문입니다 2 위니텍 2019.01.30 1313
2928 큐브리드 마이그레이션툴 사용시 질문입니다. 5 bjosbkjx 2019.01.28 265
2927 보호된 메모리를 읽거나 쓰려고 했습니다.... 2 file 모비23 2019.01.28 1190
2926 insert 관련 문의 드립니다. 2 화니 2019.01.28 115
2925 전체테이블 1 삐삐 2019.01.28 115
2924 iferror 함수 4 아영이 2019.01.18 5820
2923 현재 디비가 조회가 되지 않을정도로 느립니다. 1 file 시리 2019.01.17 247
2922 Oracle XMLAGG 함수의 유사 기능 질문드립니다. 1 jyheo 2019.01.14 704
2921 실행계획이 달라지는 경우에 대해서 문의드립니다. 2 file 동건 2019.01.13 572
2920 cubrid 의 데이터베이스 폴더 하위의 lob 폴더 내의 파일들의 정체는? 1 예림이아빠 2019.01.09 451
2919 SAP Connection 관련 질문입니다. 1 chuci 2019.01.09 195
2918 JDBC 드라이버 문제 4 황식이 2019.01.08 683
2917 Ado.net. ExecuteNonQuery의 반환값이 항상 0 입니다. 2 모비23 2019.01.08 1480
2916 Windows 10 에서 CUBRIDManager-10.1.0.0005-windows-x64와 CUBRID-Windows-x64-10.1-latest 설치후 매니저 실행하고 연결이름을 test 입력시 연결오류발생 2 file simon 2019.01.03 356
2915 java 저장 함수에서 2 klee 2018.12.27 327
Board Pagination Prev 1 ... 49 50 51 52 53 54 55 56 57 58 ... 200 Next
/ 200

Contact Cubrid

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