Background Image

FORUM

조회 수 16618 추천 수 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 으로 변경하면 정상적인 순서로 출력됩니다.


  1. No Image notice by admin 2024/04/23 by admin
    Views 72 

    CUBRID 사용자를 위한 DBeaver 도구 출시 안내

  2. SQLGate for CUBRID 영구 무료 라이선스 제공

  3. tomcat connection pool 설정방법 문의 드립니다.

  4. Cubrid2008 관련 문의 입니다.

  5. 한글 깨짐

  6. 큐브리드용 제로보드(4.1)에 대한 문의(adodb 관련)

  7. spring batch를 사용중인데 첫 실행시에만 CUBRIDResultSet 에서 NullPointerException 이 발생합니다.

  8. 큐브리드 테이블 스페이스 생성 스크립트 정보 확인 방법

  9. 설치 대상 경로에 공백있으면 설치가 안됩니다.

  10. [replication] 성능에 대한 질문입니다.

  11. php glo 접근 질문.

  12. 큐브리드 가져오기 엑셀파일 한글깨짐

  13. 저장프로시저 관련 문의 사항입니다.

  14. Date 형 쿼리 문의

  15. ha 구성시 큐브리드 매니저를 이용한 db사용자 생성 문의드립니다.

  16. MS-SQL 데이타타입/함수비교

  17. ODBC 이용 SQLHSTMT 다중으로 사용하는게 불가능한가요 ?

  18. 데이터베이스 복구 관련 질문을 다시 한번 올려봅니다. - 추가 질문 글

  19. cub_server cpu 100% 속도저하

  20. CUBRID 클라이언트만 설치 후 클라이언트 실행 에러

  21. csv 파일 import시 한글 깨짐 관련

  22. 저장 프로시져 질문

Board Pagination Prev 1 ... 9 10 11 12 13 14 15 16 17 18 ... 200 Next
/ 200

Contact Cubrid

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