Special PL syntax can be applied to any of the parameters (including the return value) in a declaration. All of these begins with __SOAP_ prefix and have special meaning. To manipulate more than the XMLSchema type representation and SOAP encoding style, extended syntax is available. With this syntax we can further override the default request/response namespace, name of the output elements, "soapAction" corresponding to the PL procedure and such.

The syntax is as follows:

   ...
   CREATE (PROCEDURE|METHOD) ([param_decl [rout_alt_type]] ...) { [BODY] } [RETURNS ....] [rout_alt_type]
   ...

rout_alt_type
        :  /* no SOAP options */
        | soap_kwd STRING opt_soap_enc_mode     /* the basic syntax */
        | __SOAP_OPTIONS '(' soap_kwd EQUALS STRING opt_soap_enc_mode ',' soap_proc_opt_list ')'/* extended syntax */
        ;

soap_proc_opt_list
        : soap_proc_opt
        | soap_proc_opt_list ',' soap_proc_opt
        ;

soap_proc_opt /* extension options as PartName:='part2' */
        : NAME EQUALS signed_literal
        ;

soap_kwd
        : __SOAP_TYPE   /* denotes XML datatype, RPC encoding style if applied to the procedure */
        | __SOAP_HEADER /* the parameter is a message in the SOAP Header */
        | __SOAP_FAULT  /* the parameter is a message in SOAP Fault */
        | __SOAP_DOC    /* applies to the procedure, free-form of encoding (literal) */
        | __SOAP_XML_TYPE /*applies to the parameters, the input will be XML tree */
        | __SOAP_DOCW           /* applies to the procedure, literal encoding in style like RPC */
        | __SOAP_HTTP           /* HTTP GET/POST binding will be used */
        ;

opt_soap_enc_mode               /* which part of traffic will be encapsulated and in what way : DIME or MIME */
        : /* no encapsulation */
        | __SOAP_DIME_ENC IN
        | __SOAP_DIME_ENC OUT
        | __SOAP_DIME_ENC INOUT
        | __SOAP_MIME_ENC IN
        | __SOAP_MIME_ENC OUT
        | __SOAP_MIME_ENC INOUT
        ;

param_decl
        : (IN|OUT|INOUT) param_name data_type_ref [(DEFAULT|:=) literal]
        ;

data_type_ref
        : (data_type_name|udt_name) [ARRAY [intnum] ...]
        ;

The above syntax can be applied to the parameter and to the whole procedure, so both places designate different purposes and limitations. When it is applied to the parameter the following keywords can be used: __SOAP_TYPE, __SOAP_HEADER, __SOAP_FAULT and __SOAP_XML_TYPE. The __SOAP_TYPE means that only XSD type will be used to interpret the data, in contrast __SOAP_XML_TYPE designates no deserialization from XML, only parses the parameter XML representation to XML tree and passes it to the procedure. The __SOAP_HEADER and __SOAP_FAULT designate that parameter will be exposed in the SOAP Header or in the SOAP Fault elements. In the second case, that parameter needs to be an 'OUT' parameter (not IN or INOUT). The string after these keywords always denotes the XSD type for SOAP serialization. When it is applied to the PL procedure (after procedure's body), the __SOAP_TYPE, __SOAP_DOC, __SOAP_DOCW, __SOAP_HTTP, __SOAP_DIME_ENC and __SOAP_MIME_ENC can be used. The string after these keywords always denotes the XSD type for SOAP serialization, except __SOAP_DIME_ENC and __SOAP_MIME_ENC which are used for other purposes and can be combined with other keywords. The __SOAP_TYPE denotes RPC style encoding, __SOAP_DOC for document literal (bare parameters) encoding, __SOAP_DOCW for the free-form literal (wrapped) encoding. __SOAP_HTTP is used to denote HTTP style binding instead of SOAP one, in that way procedure can be called via HTTP GET/POST methods without SOAP XML encoding.

The following keywords are supported as extended options:

PartName - changes the name of a OUT parameter to the string as specified, affects WSDL generation and SOAP serialization.
RequestNamespace - designate namespace for the message in the request, affects header, fault and body WSDL declaration, and serialization of SOAP in RPC encoding style.
ResponseNamespace - the same as RequestNamespace, but for SOAP response and output in WSDL declaration.
soapAction - sets the 'soapAction' attribute in WSDL generation, can be applied to the procedure only.

The RequestNamespace and ResponseNamespace can be used only for the procedure and together with the __SOAP_FAULT and __SOAP_HEADER keywords.

The 'ARRAY' modifier to the SQL datatype is allowed when no XML Schema datatype is assigned to the given parameter of the PL procedure or UDT method. In this case the input and output value will be verified to confirm to the rules applicable for an array. Furthermore in this case an XSD definition will be added in the WSDL file at run time.

Example 17.12. SOAP Extension

This example shows both approaches to define parameters and SOAP encoding style. In practice this definition is part of the Interop tests round 4 (group H). The meaning of this is: the SOAP operation is uses RPC encoding style, 'whichFault' is integer, 'param1' and 'param2' are strings. The out parameters 'part2_1' and 'part2_2' will be printed in SOAP:Fault element (see Exposing & Processing SOAP Fault Messages for more details). The interesting fact is that the last two parameters will be serialized as "part2" in different namespaces. And finally no return of the SOAP operation is defined (it's empty).

create procedure
"echoMultipleFaults3" (
    in whichFault int __soap_type 'http://www.w3.org/2001/XMLSchema:int',
    in param1 varchar __soap_type 'http://www.w3.org/2001/XMLSchema:string',
    in param2 varchar __soap_type 'http://www.w3.org/2001/XMLSchema:string',
    out part2_1 varchar __soap_options (
        __soap_fault:='http://www.w3.org/2001/XMLSchema:string',
        PartName:='part2',
        ResponseNamespace:='http://soapinterop.org/wsdl/fault1'),
    out part2_2 varchar __soap_options (
        __soap_fault:='http://www.w3.org/2001/XMLSchema:string',
        PartName:='part2',
        ResponseNamespace:='http://soapinterop.org/wsdl/fault2')
    )
   __soap_type '__VOID__'
{

  if (whichFault > 2)
    whichFault := mod (whichFault, 3) + 1;
  declare exit handler for sqlstate 'SF000'
    {
      http_request_status ('HTTP/1.1 500 Internal Server Error');
      if (whichFault = 1)
        {
          part2_1 := param1;
        }
      else if (whichFault = 2)
        {
          part2_2 := param2;
        }
      connection_set ('SOAPFault', vector ('400', 'echoMultipleFaults3'));
      return;
    };
  signal ('SF000', 'echoEmptyFault');
}
;