CREATE FUNCTION 및 CREATE PROCEDURE 문은 보통 루틴이라고 하는 호출 가능한 함수 또는 프로시저를 정의합니다.
CREATE FUNCTION 및 CREATE PROCEDURE 문은 보통 루틴이라고 하는 호출 가능한 함수 또는 프로시저를 정의합니다.
루틴은 독립적으로 여러 번 실행될 수 있는 재사용 가능 코드 블록에 유용합니다. 이는 일련의 ESQL 문, Java 메소드 또는 데이터베이스 스토어드 프로시저로 구현될 수 있습니다. 이러한 유연성은 구문 다이어그램의 일부 절이 모든 루틴 유형에 적용되지 않음을 의미합니다.
각 루틴에는 루틴이 속하는 스키마에서 고유해야 하는 이름이 있습니다. 즉, 루틴 이름은 과부하 상태가 될 수 없습니다. 루틴이 과부하 상태임을 브로커가 감지할 경우 예외가 발생합니다.
RoutineName 절을 사용하여 루틴 이름을 지정하고 ParameterList 절을 사용하여 루틴 매개변수를 지정합니다. LANGUAGE 절이 ESQL을 지정하는 경우 루틴은 ESQL 문을 사용하여 구현되어야 합니다. 이 명령문은 해당 함수를 완료하는 데 필요한 많은 ESQL 문을 포함할 수 있으므로 복합 명령문(BEGIN ... END)인 경우 유용합니다.
또한 루틴에 대해 ESQL 본문을 제공하는 대신 ESQL 이외의 LANGUAGE 절을 지정할 수 있습니다. 이를 통해 EXTERNAL NAME 절을 사용하여 브로커에 대해 외부적으로 발견되는 대로 루틴의 실제 본문에 대한 참조를 제공할 수 있습니다. EXTERNAL NAME 절 사용에 대한 자세한 정보는 저장 프로시저 호출 및 Java 루틴 호출을 참조하십시오.
LANGUAGE 유형의 루틴에는 IN, OUT 및 INOUT 매개변수가 포함될 수 있습니다. 이를 통해 호출자가 루틴에 몇 가지 값을 전달하고 몇 가지 갱신된 값을 다시 수신할 수 있습니다. 이것은 루틴이 가질 수 있는 RETURNS절에 대한 추가사항입니다. RETURNS 절을 사용하면 루틴이 값을 호출자에게 다시 전달할 수 있습니다.
서로 다른 언어로 구현된 루틴에는 데이터 유형이 전달되거나 리턴될 수 있는 자체의 제한사항이 있으며 이는 다음에서 설명됩니다. 리턴된 값의 데이터 유형은 루틴에서 리턴되도록 정의된 값의 데이터 유형과 일치해야 합니다. 또한 루틴이 리턴 값을 보유하도록 정의된 경우 루틴의 호출자가 무시할 수 없습니다. 자세한 내용은 CALL문을 참조하십시오.
언어 또는 루틴 유형의 경우 루틴의 호출 메소드는 루틴의 선언 방식과 일치해야 합니다. 루틴에 RETURNS 절이 있는 경우 FUNCTION 호출 구문을 사용하거나 INTO 절이 있는 CALL문을 사용하십시오. 반대로 RETURNS 절이 없는 경우 INTO 절 없이 CALL문을 사용해야 합니다.
루틴 유형이 FUNCTION인 경우 방향 표시기(IN, OUT, INOUT)는 각 매개변수에 대해 선택적입니다. 그러나 모든 종류의 모든 새 루틴에 방향 표시기를 지정하는 것이 좋은 프로그래밍 습관입니다.
CONSTANT로 선언된 ESQL 변수(또는 CONSTANT로 선언된 변수에 대한 참조)는 방향 OUT 또는 INOUT을 사용할 수 없습니다.
ESQL 루틴은 ESQL에서 기록되며 ESQL의 LANGUAGE 절을 보유합니다. ESQL 루틴의 본문은 주로 루틴에 전달된 매개변수를 처리하기 위한 여러 명령문을 포함하는 BEGIN … END 형식의 복합 명령문입니다.
CREATE PROCEDURE swapParms ( IN parm1 CHARACTER, OUT parm2 CHARACTER, INOUT parm3 CHARACTER ) BEGIN SET parm2 = parm3; SET parm3 = parm1; END;
이 예 프로시저에서는 ESQL 루틴의 순환적 사용을 표시합니다. 이것은 지정된 시작점 및 그 아래의 모든 위치를 방문하여 트리를 구문 분석하고 발견한 사항을 보고합니다.
SET OutputRoot.MQMD = InputRoot.MQMD; DECLARE answer CHARACTER; SET answer = ''; CALL navigate(InputRoot.XML, answer); SET OutputRoot.XML.Data.FieldNames = answer; CREATE PROCEDURE navigate (IN root REFERENCE, INOUT answer CHARACTER) BEGIN SET answer = answer || 'Reached Field... Type:' || CAST(FIELDTYPE(root) AS CHAR)|| ': Name:' || FIELDNAME(root) || ': Value :' || root || ': '; DECLARE cursor REFERENCE TO root; MOVE cursor FIRSTCHILD; IF LASTMOVE(cursor) THEN SET answer = answer || 'Field has children... drilling down '; ELSE SET answer = answer || 'Listing siblings... '; END IF; WHILE LASTMOVE(cursor) DO CALL navigate(cursor, answer); MOVE cursor NEXTSIBLING; END WHILE; SET answer = answer || 'Finished siblings... Popping up '; END;
다음의 입력 메시지가 제공된 경우,
<Person> <Name>John Smith</Name> <Salary period='monthly' taxable='yes'>-1200</Salary> </Person>
프로시저는 수동으로 형식화된 다음의 출력을 생성합니다.
Reached Field... Type:16777232: Name:XML: Value :: Field has children... drilling down Reached Field... Type:16777216: Name:Person: Value :: Field has children... drilling down Reached Field... Type:16777216: Name:Name: Value :John Smith: Field has children... drilling down Reached Field... Type:33554432: Name:: Value :John Smith: Listing siblings... Finished siblings... Popping up Finished siblings... Popping up Reached Field... Type:16777216: Name:Salary:Value :-1200: Field has children... drilling down Reached Field... Type:50331648: Name:period: Value :monthly: Listing siblings... Finished siblings... Popping up Reached Field... Type:50331648: Name:taxable: Value :yes: Listing siblings... Finished siblings... Popping up Reached Field... Type:33554432: Name:: Value :-1200: Listing siblings... Finished siblings... Popping up Finished siblings... Popping up Finished siblings... Popping up Finished siblings... Popping up
>>--"-- className---.---methodName--"--------------><여기서 className은 메소드를 포함하는 클래스를 식별하고 methodName은 호출할 메소드를 식별합니다. 클래스가 패키지의 일부인 경우, 클래스 ID 부분에 완전한 패키지 접두부가 포함되어야 합니다. 예: "com.ibm.broker.test.MyClass.myMethod"
Java 클래스를 찾기 위해 브로커는 Java 클래스 전개에 설명된 대로 검색합니다.
public static <return-type> <method-name> (< 0 - N parameters>)
여기에서 <return-type>은 ESQL 대 Java 데이터 유형 맵핑 테이블의 Java IN 데이터 유형 목록에 포함되거나(리턴 값으로 허용되지 않는 REFERENCE 유형 제외) 또는 Java void 데이터 유형 목록에 포함되어야 합니다. 매개변수 데이터 유형도 ESQL 대 Java 데이터 유형 맵핑 테이블에서 가져와야 합니다. 또한 Java 메소드는 서명에 예외 전달 절을 포함할 수 없습니다.
Java 메소드에 Java UDN(사용자 정의 노드) API를 사용할 수 있으며 Java 루틴 제한사항에 문서화된 제한사항을 준수한다고 가정합니다. UDN API 사용에 대한 자세한 정보는, Java 사용자 정의 노드 컴파일을 참조하십시오.
이 루틴에는 세 개의 방향 매개변수가 포함되고 정수를 리턴하여 java.lang.Long의 Java 리턴 유형으로 맵핑합니다.
CREATE FUNCTION myProc1( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER ) RETURNS INTEGER LANGUAGE JAVA EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod1";
다음 ESQL을 사용하여 myProc1을 호출할 수 있습니다.
CALL myProc1( intVar1, intVar2, intVar3) INTO intReturnVar3; -- or SET intReturnVar3 = myProc1( intVar1, intVar2, intVar3);
이 루틴에는 세 개의 방향 매개변수가 포함되며 Java 리턴 유형 void가 있습니다.
CREATE PROCEDURE myProc2( IN P1 INTEGER, OUT P2 INTEGER, INOUT P3 INTEGER ) LANGUAGE JAVA EXTERNAL NAME "com.ibm.broker.test.MyClass.myMethod2";
다음 ESQL을 사용하여 myProc2를 호출해야 합니다.
CALL myProc2(intVar1, intVar2, intVar3);
다음 Java 클래스는 앞의 Java 예 각각에 대한 메소드를 제공합니다.
package com.ibm.broker.test; class MyClass { public static Long myMethod1( Long P1, Long[] P2 Long[] P3) { ... } public static void myMethod2( Long P2, Long[] P2 Long[] P3) { ... } /* When either of these methods is called: P1 may or may not be NULL (depending on the value of intVar1). P2[0] is always NULL (whatever the value of intVar2). P3[0] may or may not be NULL (depending on the value of intVar3). This is the same as with LANGUAGE ESQL routines. When these methods return: intVar1 is unchanged intVar2 may still be NULL or may have been changed intVar3 may contain the same value or may have been changed. This is the same as with LANGUAGE ESQL routines. When myMethod1 returns: intReturnVar3 is either NULL (if the method returns NULL) or it contains the value returned by the method. */ }
ESQL 데이터 유형 1 | Java IN 데이터 유형 | Java INOUT 및 OUT 데이터 유형 |
INTEGER, INT | java.lang.Long | java.lang.Long [] |
FLOAT | java.lang.Double | java.lang.Double[] |
DECIMAL | java.math.BigDecimal | java.math.BigDecimal[] |
CHARACTER, CHAR | java.lang.String | java.lang.String[] |
BLOB | byte[] | byte[][] |
BIT | java.util.BitSet | java.util.BitSet[] |
DATE | com.ibm.broker.plugin.MbDate | com.ibm.broker.plugin.MbDate[] |
TIME 2 | com.ibm.broker.plugin.MbTime | com.ibm.broker.plugin.MbTime[] |
GMTTIME 2 | com.ibm.broker.plugin.MbTime | com.ibm.broker.plugin.MbTime[] |
TIMESTAMP 2 | com.ibm.broker.plugin.MbTimestamp | com.ibm.broker.plugin.MbTimestamp[] |
GMTTIMESTAMP 2 | com.ibm.broker.plugin.MbTimestamp | com.ibm.broker.plugin.MbTimestamp[] |
INTERVAL | 지원되지 않음 | 지원되지 않음 |
BOOLEAN | java.lang.Boolean | java.lang.Boolean[] |
REFERENCE(메시지 트리에 대한) 3 4 5 6 | com.ibm.broker.plugin.MbElement | com.ibm.broker.plugin.MbElement[] (INOUT에 대해 지원됨. OUT에 대해서는 지원되지 않음) |
ROW | 지원되지 않음 | 지원되지 않음 |
LIST | 지원되지 않음 | 지원되지 않음 |
예를 들면, OutputRoot.XML.Test에 대한 ESQL 참조가 INOUT MbElement로 Java 메소드에 전달되지만 호출 리턴 시 다른 MbElement가 다시 ESQL로 전달되는 경우, 다른 요소도 OutputRoot 트리 내의 위치를 가리켜야 합니다.
참조가 나타내는 변수의 데이터 유형이 Java 프로그램 서명의 해당 데이터 유형과 일치하는 경우에 스칼라 변수에 대한 REFERENCE를 Java 메소드의 CALL에서 사용할 수 있습니다.
메소드에서는 파생된 스레드만 허용됩니다. 그러나, 파생된 스레드는 Java 플러그인 API를 사용하면 안되고 브로커로 제어를 리턴해야 합니다.
UDN API 사용에 적용되는 모든 제한은 ESQL에서 호출된 Java 메소드에도 적용됩니다.
JAR 파일을 BAR 파일에 추가하는 방법이 브로커에 전개하는 가장 효율적이고 유연한 방법입니다.
도구를 사용하여 수동으로 또는 자동으로 BAR 파일에 JAR 파일을 추가할 수 있습니다. 도구를 사용하는 것이 JAR 파일을 BAR 파일에 추가하는 가장 간단한 방법입니다.
도구는 참조된 Java 프로젝트 내의 올바른 Java 클래스가 작업 공간에서 열려 있음을 발견하면 Java 클래스를 JAR 파일로 컴파일하고 BAR 파일에 추가합니다. 이는 사용자 정의 노드 클래스 로딩에 설명된 대로 JAR 내의 Java Compute 노드를 전개하기 위해 따르는 프로시저와 동일합니다.
도구에서 JAR 파일을 전개할 때 JAR 파일이 들어 있는 BAR 파일을 재전개하면 Java 클래스를 참조하는 메시지 플로우를 정지하고 재시작하므로 참조된 Java 클래스가 재전개된 플로우에 의해 다시 로드됩니다. 갱신하려는 JAR 파일을 참조하는 플로우를 모두 정지하고 재시작(또는 재전개)하십시오. 이렇게 하면 이전 버전의 JAR 파일을 사용하여 실행 중인 일부 플로우 및 새 버전을 사용하여 실행 중인 기타 플로우의 문제점을 방지할 수 있습니다.
도구는 JAR 파일만 전개하고 독립형 Java 클래스 파일은 전개하지 않음을 참고하십시오.
반드시 이 프로시저를 수동으로 수행해야 합니다. 그렇지 않으면 도구를 사용할 수 없습니다.
이 메소드에서는 메시지 플로우를 재전개해도 참조된 Java 클래스가 다시 로드되지 않습니다. 메시지 플로우를 정지하고 재시작하지도 않습니다. 이 경우 클래스를 다시 로드하는 유일한 방법은 브로커 자체를 정지하고 재시작하는 것입니다.
브로커가 Java 클래스를 찾을 수 있도록 하려면 위의 위치 중 하나에 있는지 확인하십시오. 브로커가 지정된 클래스를 찾을 수 없는 경우 예외를 전달합니다.
JAR 파일을 전개할 때 위에 표시된 방법 중에서 선택할 수 있긴 하지만 도구를 사용하여 BAR 파일을 전개하면 JAR 파일 재전개 시 최대한의 유연성을 제공합니다.
데이터베이스 루틴은 데이터베이스 스토어드 프로시저로 구현된 루틴입니다. 데이터베이스 루틴에는 DATABASE의 LANGUAGE 절이 있으며 PROCEDURE의 루틴 유형도 있어야 합니다.
C와 같은 언어로 스토어드 프로시저를 작성할 경우에는 널(null) 표시기를 사용하여 프로시저가 데이터를 올바르게 처리할 수 있는지 확인해야 합니다.
스토어드 프로시저의 데이터베이스 정의는 데이터베이스에 따라 다르지만 호출에 사용된 ESQL은 다르지 않습니다. ESQL의 매개변수에 제공된 이름은 데이터베이스 측에서 제공된 이름과 일치할 필요가 없습니다. 그러나 패키지 또는 컨테이너 스팩과 같은 루틴의 외부 이름은 데이터베이스에 정의된 이름과 일치해야 합니다.
DYNAMIC RESULT SET 절은 데이터베이스 루틴에만 허용됩니다. 스토어드 프로시저가 하나 이상의 결과 세트를 리턴하는 경우에만 필요합니다. 이 절에 대한 정수 매개변수는 0 이상이어야 하며 리턴할 결과 세트의 수를 지정합니다.
선택적 RETURNS 절은 스토어드 프로시저가 단일 스칼라 값을 리턴하는 경우에 필요합니다.
EXTERNAL NAME 절은 데이터베이스에서 루틴을 아는 이름을 지정합니다. 규정되거나 규정되지 않은 이름이 될 수 있습니다. 여기서 규정자는 프로시저가 정의된 데이터베이스 스키마의 이름입니다. 스키마 이름을 제공하지 않으면 데이터베이스 연결 사용자 이름이 프로시저를 찾을 스키마로 사용됩니다. 이 스키마에 필요한 프로시저가 없으면 런타임으로 루틴 정의나 루틴에 대한 CALL에서 명확한 스키마 이름을 제공해야 합니다. 루틴을 포함하는 스키마를 동적으로 선택하는 것에 대한 자세한 정보는 CALL문을 참조하십시오. 규정된 이름이 사용되면 이 이름은 큰따옴표로 묶여야 합니다.
EXTERNAL NAME "mySchema.myProc";
EXTERNAL NAME "mySchema.myPackage.myProc";
이를 통해 CALL문에서 패키지 이름은 제외하고 스키마 이름을 동적으로 선택할 수 있습니다.
EXTERNAL NAME "mySchema.Proc_";
다음은 단일 스칼라 값 및 OUT 매개변수를 리턴하는 스토어드 프로시저의 단순 ESQL 정의입니다.
CREATE PROCEDURE myProc1(IN P1 INT, OUT P2 INT) LANGUAGE DATABASE RETURNS INTEGER EXTERNAL NAME "myschema.myproc";
이 ESQL을 사용하여 myProc1 루틴을 호출하십시오.
/*using CALL statement invocation syntax*/ CALL myProc1(intVar1, intVar2) INTO intReturnVar3; /*or using function invocation syntax*/ SET intReturnVar3 = myProc1(intVar1, intVar2);
다음 ESQL 코드는 DB2 스토어드 프로시저를 정의하고 호출하는 방법에 대해 설명합니다.
ESQL 정의: DECLARE inputParm CHARACTER; DECLARE outputParm CHARACTER; DECLARE inputOutputParm CHARACTER; SET inputParm = 'Hello'; SET inputOutputParm = 'World'; CALL swapParms( inputParm, outputParm, inputOutputParm ); CREATE PROCEDURE swapParms ( IN parm1 CHARACTER, OUT parm2 CHARACTER, INOUT parm3 CHARACTER ) EXTERNAL NAME dbSwapParms;
DB2를 사용하여 저장 프로시저를 등록하려면 파일(예:test1.sql)에 다음의 스크립트를 복사하십시오.
-- DB2 Example Stored Procedure DROP PROCEDURE dbSwapParms @ CREATE PROCEDURE dbSwapParms ( IN in_param CHAR(32), OUT out_param CHAR(32), INOUT inout_param CHAR(32)) LANGUAGE SQL BEGIN SET out_param = inout_param; SET inout_param = in_param; END @다음을 실행하십시오.
db2 -td@ -vf test1.sql을 실행하십시오.
다음 ESQL 코드는 Oracle 스토어드 프로시저를 정의하고 호출하는 방법에 대해 설명합니다.
ESQL 정의: DECLARE inputParm CHARACTER; DECLARE outputParm CHARACTER; DECLARE inputOutputParm CHARACTER; SET inputParm = 'Hello'; SET inputOutputParm = 'World'; CALL swapParms( inputParm, outputParm, inputOutputParm ); CREATE PROCEDURE swapParms ( IN parm1 CHARACTER, OUT parm2 CHARACTER, INOUT parm3 CHARACTER ) EXTERNAL NAME dbSwapParms;
Oracle를 사용하여 저장 프로시저를 등록하려면 파일(예:test1.sql)에 다음의 스크립트를 복사하십시오.
CREATE OR REPLACE PROCEDURE dbSwapParms ( in_param IN VARCHAR2 , out_param OUT VARCHAR2, inout_param IN OUT VARCHAR2 ) AS BEGIN out_param := inout_param; inout_param := in_param; END; /다음을 실행하십시오.
sqlplus <userid>/<password> @test1.sql
다음 ESQL 코드는 SQL 스토어드 프로시저를 정의하고 호출하는 방법에 대해 설명합니다.
ESQL 정의: DECLARE inputParm CHARACTER; DECLARE outputParm CHARACTER; DECLARE inputOutputParm CHARACTER; SET inputParm = 'Hello'; SET inputOutputParm = 'World'; CALL swapParms( inputParm, outputParm, inputOutputParm ); CREATE PROCEDURE swapParms ( IN parm1 CHARACTER, INOUT parm2 CHARACTER, INOUT parm3 CHARACTER ) EXTERNAL NAME dbSwapParms;
SQLServer를 사용하여 저장 프로시저를 등록하려면 파일(예:test1.sql)에 다음의 스크립트를 복사하십시오.
-- SQLServer Example Stored Procedure DROP PROCEDURE dbSwapParms go CREATE PROCEDURE dbSwapParms @in_param CHAR(32), @out_param CHAR(32) OUT, @inout_param CHAR(32) OUT AS SET NOCOUNT ON SET @out_param = @inout_param SET @inout_param = @in_param go다음을 실행하십시오.
isql -U<userid> -P<password> -S<server> -d<datasource> -itest1.sql
ESQL에서 해당 매개변수를 OUT 매개변수로 선언하면 런타임 시 유형 불일치 오류가 발생합니다. 불일치 오류를 방지하려면 SQL 서버 OUTPUT 매개변수를 ESQL에서 INOUT으로 선언해야 합니다.
다음 ESQL 코드는 SYBASE 스토어드 프로시저를 정의하고 호출하는 방법에 대해 설명합니다.
ESQL 정의: DECLARE inputParm CHARACTER; DECLARE outputParm CHARACTER; DECLARE inputOutputParm CHARACTER; SET inputParm = 'Hello'; SET inputOutputParm = 'World'; CALL swapParms( inputParm, outputParm, inputOutputParm ); CREATE PROCEDURE swapParms ( IN parm1 CHARACTER, INOUT parm2 CHARACTER, INOUT parm3 CHARACTER ) EXTERNAL NAME dbSwapParms;
SYBASE를 사용하여 이 스토어드 프로시저를 등록하려면 다음 스크립트를 파일(예: test1.sql)에 복사하십시오.
-- SYBASE 스토어드 프로시저 예 DROP PROCEDURE dbSwapParms go CREATE PROCEDURE dbSwapParms @in_param CHAR(32), @out_param CHAR(32) OUT, @inout_param CHAR(32) OUT AS SET @out_param = @inout_param SET @inout_param = @in_param go다음을 실행하십시오.
isql -U<userid> -P<password> -S<server> -d<datasource> -itest1.sql
ESQL에서 해당 매개변수를 OUT 매개변수로 선언하면 런타임 시 유형 불일치 오류가 발생합니다. 불일치 오류를 방지하려면 SYBASE OUTPUT 매개변수를 ESQL에서 INOUT으로 선언해야 합니다.
이 예는 두 개의 결과 세트 및 out 매개변수를 리턴하는 스토어드 프로시저를 호출하는 방법에 대해 표시합니다.
CREATE PROCEDURE myProc1 (IN P1 INT, OUT P2 INT) LANGUAGE DATABASE DYNAMIC RESULT SETS 2 EXTERNAL NAME "myschema.myproc";
다음 ESQL을 사용하여 myProc1을 호출합니다.
/* using a field reference */ CALL myProc1(intVar1, intVar2, Environment.RetVal[], OutputRoot.XML.A[]) /* using a reference variable*/ CALL myProc1(intVar1, intVar2, myReferenceVariable.RetVal[], myRef2.B[])