• HANA SQL Script学习(3):Logic Container


    3Logic Container

    /*

    2.Logic Container

           逻辑代码块分类:1.Procedure;2.User-Defined Function

           User-Defined Function分类:Scalar User-Defined Function and Table User-Defined Function.

    3.1 Procedure

    --2.1创建procedure

    语法:

     CREATE [OR REPLACE] PROCEDURE <proc_name>

      [(<parameter_clause>)]

      [LANGUAGE <lang>]

      [SQL SECURITY <mode>]

      [DEFAULT SCHEMA <default_schema_name>]

      [READS SQL DATA ]

      [WITH ENCRYPTION]

      [AUTOCOMMIT DDL ON|OFF] 

      AS

      BEGIN

        [SEQUENTIAL EXECUTION]  

           <procedure_body>

      END

    <proc_name> ::= [<schema_name>.]<identifier>

    <parameter_clause> ::= <parameter> [{, <parameter>}...]

    <param_inout> ::= IN | OUT | INOUT

    默认IN

    <param_type> ::= <sql_type> [ARRAY] | <table_type> | <table_type_definition> | <any_table_type>

    <sql_type> ::= DATE | TIME| TIMESTAMP | SECONDDATE | TINYINT | SMALLINT | INTEGER | BIGINT

                            |DECIMAL | SMALLDECIMAL | REAL | DOUBLE

                   | VARCHAR | NVARCHAR | ALPHANUM | VARBINARY | CLOB | NCLOB | BLOB | ST_GEOMETRY | ARRAY

    <table_type_definition>   ::=  TABLE (<column_list_definition>)

    <column_list_definition> ::= <column_elem>[{, <column_elem>}...]

    <column_elem> ::= <column_name> <data_type>

    LANGUAGE <lang>

      <lang> ::= SQLSCRIPT | R

    指定语言,默认SQLSCRIPT

    SQL SECURITY <mode>

      <mode> ::= DEFINER | INVOKER

    指定安全模式,默认DEFINER.DEFINER:以procedure创建者权限执行;INVOKER:以procedure执行时的权限执行;

    DEFAULT SCHEMA <default_schema_name>

     <default_schema_name> ::= <unicode_name>

    默认当前schema

    READS SQL DATA

    只读,没有DDL(数据库表视图的增删改)和DML(数据记录的增删改)语句

    AUTOCOMMIT DDL ON|OFF

    默认:OFF,某些语句必须ON才能使用,例如:IMPORT

    SEQUENTIAL EXECUTION

    强制顺序执行,不会并行

    <procedure_body> ::= [<proc_decl_list>][<proc_handler_list>] <proc_stmt_list>

    <proc_decl_list> ::= <proc_decl> [{, <proc_decl>}…]

    <proc_decl> ::= DECLARE  {<proc_variable>|<proc_table_variable>|<proc_cursor>| <proc_condition>} ;

           <proc_cursor> ::= CURSOR <cursor_name> [ ( proc_cursor_param_list ) ] FOR <subquery> ;

                  <cursor_name>::= <identifier>

                  <proc_cursor_param_list> ::= <proc_cursor_param> [{, <proc_cursor_param>}...]

                         <proc_cursor_param>::= <param_name> <datatype>

    <proc_variable>::= <variable_name_list> [CONSTANT] {<sql_type>| <array_datatype>}[NOT NULL][<proc_default>]

           <array_datatype>::= <sql_type> ARRAY [ = <array_constructor> ]

                  <array_constructor>::= ARRAY (<expression> [ { , <expression> }...] )

           <proc_default>::= (DEFAULT | '=' ) <value>|<expression>

                  <value>::= An element of the type specified by <type> or an expression

    <proc_table_variable> ::= <variable_name_list> {<table_type_definition>| <table_type>}

           <variable_name_list>::= <variable_name>[{, <variable_name}...]

    <column_list_elements>::= (<column_definition>[{,<column_definition>}...])

    <proc_condition>::= <variable_name> CONDITION | <variable_name> CONDITION FOR <sql_error_code>

           <variable_name>::= <identifier>

    <proc_handler_list> ::= <proc_handler> [{, <proc_handler>}...]

    <proc_handler>::= DECLARE EXIT HANDLER FOR <proc_condition_value_list> <proc_stmt> ;

    <proc_condition_value_list> ::= <proc_condition_value> {,<proc_condition_value>}...]

    <proc_condition_value> ::= SQLEXCEPTION | <sql_error_code> | <condition_name>

    <proc_stmt_list> ::= {<proc_stmt>}...

    <proc_stmt> ::= <proc_block> | <proc_assign> | <proc_single_assign> | <proc_multi_assign> | <proc_if>              

                         | <proc_loop>    | <proc_while>  | <proc_for>           | <proc_foreach>      | <proc_exit>              

                   | <proc_continue>| <proc_signal> | <proc_resignal>      | <proc_sql>          | <proc_open>              

                      | <proc_fetch>   | <proc_close>  | <proc_call>          | <proc_exec>         | <proc_return>              

                   | <proc_insert>  | <proc_update> | <proc_delete>

    <proc_insert> ::= :<table_variable>.INSERT((<value_1>,…, <value_n>), <index>)

    <proc_update> ::= :<table_variable>.UPDATE((<value_1>,…, <value_n>), <index>)

    <proc_update> ::= <table_variable>[<index>] = (<value_1>,…, <value_n>)

    <proc_delete> ::= :<table_variable>.DELETE(<index>)

    <proc_delete> ::= :<table_variable>.DELETE(<from_index>..<to_index>)

    <proc_block> ::=

           BEGIN <proc_block_option>

                  [<proc_decl_list>]                 

                  [<proc_handler_list>]                 

                  <proc_stmt_list>             

           END ;

    <proc_block_option> ::= 

           [SEQUENTIAL EXECUTION ]

      | [AUTONOMOUS TRANSACTION]

      | [PARALLEL EXECUTION]

    <proc_assign> ::= <variable_name> = { <expression> | <array_function> } ;

                      | <variable_name> '[' <expression> ']' = <expression>  ;

           <array_function> = ARRAY_AGG   ( :<table_variable>.<column_name> [ ORDER BY <sort_spec_list> ] )

                     | CARDINALITY ( :<array_variable_name>)

                     | TRIM_ARRAY  ( :<array_variable_name> , <array_variable_name>)                    

                     | ARRAY ( <array_variable_name_list> ) 

           <table_variable>      ::= <identifier>

           <column_name>         ::= <identifier>

           <array_variable_name> ::= <identifier>

    <proc_multi_assign> ::= (<var_name_list>) = <function_expression>

    <proc_single_assign> ::= <variable_name> = <subquery>

                            |  <variable_name> = <proc_ce_call>                      

                                             |  <variable_name> = <proc_apply_filter>                      

                                             |  <variable_name> = <unnest_function>

                            |  <variable_name> = <map_merge_op>

    <map_merge_op> ::= MAP_MERGE(<table_or_table_variable>, <mapper_identifier>(<table_or_table_variable>.<column_name> [ {, <table_or_table_variable>.<column_name>} … ] [, <param_list>])

    <table_or_table_variable> ::= <table_variable_name> | <identifier>

    <table_variable_name> ::= <identifier>

    <mapper_identifier> ::= <identifier>

    <column_name> ::= <identifier>

    <param_list> ::= <param> [{, <param>} …]

    <paramter> = <table_or_table_variable> | <string_literal> | <numeric_literal> | <identifier>

    <proc_ce_call> ::= TRACE ( <variable_name> ) ;

        | CE_LEFT_OUTER_JOIN ( <table_variable> , <table_variable> , '[' <expr_alias_comma_list> ']' [ <expr_alias_vector>]  ) ;                 

           | CE_RIGHT_OUTER_JOIN ( <table_variable> , <table_variable> , '[' <expr_alias_comma_list> ']' [ <expr_alias_vector>] ) ;                 

           | CE_FULL_OUTER_JOIN ( <table_variable> , <table_variable> , '[' <expr_alias_comma_list> ']' [ <expr_alias_vector>]  );                 

           | CE_JOIN ( <table_variable> , <table_variable> , '[' <expr_alias_comma_list> ']' [<expr_alias_vector>]  ) ;                 

           | CE_UNION_ALL ( <table_variable> , <table_variable> ) ;                 

           | CE_COLUMN_TABLE ( <table_name> [ <expr_alias_vector>]  ) ;                 

           | CE_JOIN_VIEW ( <table_name> [ <expr_alias_vector>] ) ;                  

           | CE_CALC_VIEW ( <table_name> [ <expr_alias_vector>] ) ;                 

           | CE_OLAP_VIEW ( <table_name> [ <expr_alias_vector>] ) ;                 

           | CE_PROJECTION ( <table_variable> , '[' <expr_alias_comma_list> ']' <opt_str_const> ) ;                  

           | CE_PROJECTION ( <table_variable> <opt_str_const> ) ;                  

           | CE_AGGREGATION ( <table_variable> , '[' <agg_alias_comma_list> ']' [ <expr_alias_vector>] );                  

           | CE_CONVERSION ( <table_variable> , '[' <proc_key_value_pair_comma_list> ']' [ <expr_alias_vector>] ) ;                  

           | CE_VERTICAL_UNION ( <table_variable> , '[' <expr_alias_comma_list> ']' <vertical_union_param_pair_list> ) ;                  

           | CE_COMM2R ( <table_variable> , <int_const> , <str_const> , <int_const> , <int_const> , <str_const> ) ; 

           <table_name>  ::= [<schema_name>.]<identifier>

    <proc_apply_filter> ::= APPLY_FILTER ( {<table_name> | :<table_variable>}, <variable_name> ) ;

    <unnest_function> ::= UNNEST ( <variable_name_list> ) [ WITH ORDINALITY ] [<as_col_names>] ;

     <variable_name_list> ::= :<variable_name> [{, :<variable_name>}...]

     WITH ORDINALTIY:添加ordinal列

     <as_col_names> ::= AS [table_name] ( <column_name_list> )

     <column_name_list> ::= <column_name>[{, <column_name>}...] <column_name> ::= <identifier>

     返回表名,列名

    if 语句

    <proc_if> ::= IF <condition> THEN

                               [SEQUENTIAL EXECUTION][<proc_decl_list>]

                               [<proc_handler_list>]

                               <proc_stmt_list>

                    [<proc_elsif_list>]

                               [<proc_else>]              

                           END IF ;

    <proc_elsif_list> ::= ELSEIF <condition> THEN

                               [SEQUENTIAL EXECUTION]

                               [<proc_decl_list>]

                               [<proc_handler_list>]

                               <proc_stmt_list> 

    <proc_else> ::= ELSE

                               [SEQUENTIAL EXECUTION]

                               [<proc_decl_list>]

                               [<proc_handler_list>]

                               <proc_stmt_list>

    loop 语句

    <proc_loop> ::=

           LOOP

                  [SEQUENTIAL EXECUTION]

                  [<proc_decl_list>]

                  [<proc_handler_list>]

                  <proc_stmt_list>

           END LOOP ;

    while 语句

    <proc_while> ::=

           WHILE <condition> DO

                  [SEQUENTIAL EXECUTION]

                  [<proc_decl_list>]

                  [<proc_handler_list>]

                  <proc_stmt_list>

           END WHILE ;

    for 语句

    <proc_for> ::=

           FOR <column_name> IN [ REVERSE ] <expression> [...] <expression> DO

                  [SEQUENTIAL EXECUTION]

                  [<proc_decl_list>]

                  [<proc_handler_list>]

                  <proc_stmt_list>           

        END FOR ;

    foreach 语句:

    <proc_foreach> ::=

           FOR <column_name> AS <column_name> [<open_param_list>] DO

                  [SEQUENTIAL EXECUTION]

                  [<proc_decl_list>]

                  [<proc_handler_list>]

                  <proc_stmt_list>                

           END FOR ;

    <open_param_list> ::= ( <expression> [ { , <expression> }...] )

    跳出循环语句:

    <proc_exit> ::= BREAK ;

    跳过本次循环,继续下次:

    <proc_continue> ::= CONTINUE ;

    定义signal,显式抛出异常

    <proc_signal> ::=  SIGNAL <signal_value> [<set_signal_info>] ;

    定义resignal,捕获异常

    <proc_resignal> ::= RESIGNAL [<signal_value>] [<set_signal_info>] ;

           <signal_value>   ::= <signal_name> | <sql_error_code>

           <signal_name>    ::= <identifier>

           <sql_error_code> ::= <unsigned_integer>

           <set_signal_info> ::= SET MESSAGE_TEXT = '<message_string>'

         <message_string>  ::= <any_character>

    sql语句

    <proc_sql> ::=  <subquery> | <select_into_stmt> | <insert_stmt>                

                               | <delete_stmt> | <update_stmt> | <replace_stmt>                

                               | <call_stmt> | <create_table>  | <drop_table>               

                               | <truncate_statement>

    查询语句

    <select_into_stmt> ::= SELECT <select_list> INTO <var_name_list> [DEFAULT <scalar_expr_list>]

                             <from_clause >                       

                                              [<where_clause>]                       

                                              [<group_by_clause>]                       

                                              [<having_clause>]                         

                                              [{<set_operator> <subquery>, ... }]                       

                                              [<order_by_clause>]

                             [<limit>] ;

    <var_name_list> ::= <var_name>[{, <var_name>}...]

    <var_name>      ::= <identifier>

    Cursor操作

    <proc_open>  ::= OPEN <cursor_name> [ <open_param_list>] ;

    <proc_fetch> ::= FETCH <cursor_name> INTO <column_name_list> ;

    <proc_close> ::= CLOSE <cursor_name> ;

    调用procedure

    <proc_call> ::= CALL <proc_name> (<param_list>) ;

    执行调用动态SQL

    <proc_exec> ::= {EXEC | EXECUTE IMMEDIATE} <proc_expr> ;

    返回procedure值

    <proc_return> ::= RETURN [<proc_expr>] ;

    /*
    实例1:创建procedure,显示信息
    //创建table:message_box */ CREATE TABLE test_message_box (p_msg VARCHAR(200), tstamp TIMESTAMP); CREATE PROCEDURE insert_msg_proc (p_msg VARCHAR(200)) LANGUAGE SQLSCRIPT AS BEGIN INSERT INTO test_message_box VALUES (:p_msg, CURRENT_TIMESTAMP); END;
    /*
    实例:2
    //创建cursor,调用cursor。
    */
    CREATE PROCEDURE test_proc1
          LANGUAGE SQLSCRIPT AS
    BEGIN  
           DECLARE v_id STRING; 
           DECLARE v_name STRING;  
           DECLARE v_price DECIMAL(10,2);  
           DECLARE v_msg VARCHAR(200);  
    
           DECLARE CURSOR c_cursor1 (p_price DECIMAL(10,2)) FOR    
           SELECT "Product_ID","Product_Name","Price" FROM "MyProducts"   
                  WHERE "Price" > :p_price
                  ORDER BY "Product_ID" ASC;  
           OPEN c_cursor1(40);  
           FETCH c_cursor1 INTO v_id, v_name, v_price;
           v_msg = :v_name || ' (id ' || :v_id || ') sell ' || :v_price || ' $.';  
           CALL insert_msg_proc(:v_msg);  
           CLOSE c_cursor1;
    END;

    /*

    2.1.2 调用procedure

    CALL <proc_name> (<param_list>) [WITH OVERVIEW]

    <proc_name> ::= [<schema_name>.]<identifier>

    <param_list> ::= <proc_param>[{, <proc_param>}...]

    <proc_param> ::= <identifier> | <string_literal> | <unsigned_integer> | <signed_integer>| <signed_numeric_literal> | <unsigned_numeric_literal> | <expression>

    [WITH OVERVIEW]

    当返回值为表数据集时,将数据插入对应OUT参数表;如果OUT ?,临时表保存返回数据

    procedure内部调用procedure

    CALL <proc_name > (<param_list>)

    <param_list> ::= <param>[{, <param>}...]

    <param>::= <in_table_param> | <in_scalar_param> |<out_scalar_param> | <out_table_param>| <inout_scalar_param>

    <in_table_param> ::= <in_param>

    <in_param> ::= :<identifier>

    <in_scalar_param> ::= <in_param>|<scalar_value>|<expression>

    <out_param> ::= <identifier>

    <out_scalar_param> ::= <out_ param>

    <out_table_param> ::= <out_ param>

    <inout_scalar_param> ::= <out_ param>

    创建procedure时,设置默认值

    IN <param_name>  (<sql_type>|<table_type>|<table_type_definition>) DEFAULT (<value>|<table_name>)

    当参数类型为table时,可以设置为empty

    (IN|OUT) <param_name> (<table_type>|<table_type_definition>) DEFAULT EMPTY

    */

    CALL test_proc1();
    
    /*创建test procedure 表*/
    CREATE TABLE TEST_PROC( id INT,name VARCHAR(10),val DECIMAL(10,2) );
    CREATE TABLE TEST_PROC_TEMP( id INT,name VARCHAR(10),val DECIMAL(10,2) );
    INSERT INTO TEST_PROC VALUES( 1, 'test1', 4.32 );
    INSERT INTO TEST_PROC VALUES( 2, 'test2', 1.43 );
    INSERT INTO TEST_PROC VALUES( 3, 'test3', 20.63 );
    
    /*创建table类型*/
    CREATE TYPE TYPETABLE AS TABLE ( id INTEGER,name VARCHAR(10),val DECIMAL(10,2) );
    
    /*创建procedure2*/
    CREATE PROCEDURE test_proc2(IN id INTEGER,OUT resTab TYPETABLE)
           LANGUAGE SQLSCRIPT AS
    BEGIN
           resTab = SELECT * FROM TEST_PROC WHERE id = :id;
    END;
    
    /*调用procedure*/
    CALL test_proc2(1,?);
    CALL test_proc2(2,?) WITH OVERVIEW;
    CALL test_proc2(2+1,?);
    /*使用物理表作为参数时,必须使用with overview,会将返回结果写入物理表中*/
    CALL test_proc2(1,test_proc_temp) WITH OVERVIEW;
    /*直接通过参数名调用procedure,这样可以忽略参数顺序*/
    CALL test_proc2(resTab=>?,id=>2);
    
    /*创建procedure3*/
    CREATE PROCEDURE test_proc3(int1 INTEGER,intab TYPETABLE)
           LANGUAGE SQLSCRIPT AS
    BEGIN
           SELECT int1 AS "变量" FROM DUMMY;
           SELECT * FROM :intab;
    END;
    /*传入参数,表*/
    CALL test_proc3(1,TEST_PROC);
    CALL test_proc3(2,"TEST_PROC");
    
    
    /*创建procedure4*/
    CREATE PROCEDURE test_proc4( IN intab TABLE( id INTEGER) DEFAULT EMPTY)
           LANGUAGE SQLSCRIPT AS
    BEGIN
           IF IS_EMPTY(:intab) THEN
                  SELECT 'input is empty' FROM DUMMY;
           ELSE
                  SELECT 'input is not empty' FROM DUMMY;
           END IF;
    END;
    CALL test_proc4();

    /*

    2.1.3删除procedure

    DROP PROCEDURE <proc_name> [<drop_option>]

    <proc_name> ::= [<schema_name>.]<identifier

    <drop_option> ::= CASCADE | RESTRICT

    CASCADE:级联删除,当procedure被其他procedure调用,级联删除

    RESTRICT:当procedure被其他procedure调用,删除时报错

    */

    DROP PROCEDURE test_proc1;

    /*

    2.1.4修改procedure

    ALTER PROCEDURE <proc_name> [(<parameter_clause>)] [LANGUAGE <lang>]

     [DEFAULT SCHEMA <default_schema_name>]

     [READS SQL DATA] AS

     BEGIN

           [SEQUENTIAL EXECUTION]  <procedure_body>

     END

    ALTER PROCEDURE <proc_name> RECOMPILE

    通过生成更新执行计划触发重新编译

    */

    /*

    2.1.5 procedure信息

    Table:SYS.PROCEDURES

    可用的procedure信息

    表字段说明:

    SCHEMA_NAME:shema名称

    PROCEDURE_NAME:procedure名称

    PROCEDURE_OID:procedure ID

    SQL_SECURITY:SQL安全设置'DEFINER' / 'INVOKER'

    DEFAULT_SCHEMA_NAME:Schema name of the unqualified objects in the procedure

    INPUT_PARAMETER_COUNT:输入参数数量

    OUTPUT_PARAMETER_COUNT:输出参数数量

    INOUT_PARAMETER_COUNT:INOUT参数数量

    RESULT_SET_COUNT:result set 计数

    IS_UNICODE:是否包含 Unicode or not: 'TRUE'/ 'FALSE'

    DEFINITION:procedure定义文本

    PROCEDURE_TYPE:procedure类型

    READ_ONLY:whether the procedure is read-only or not: 'TRUE'/ 'FALSE'

    IS_VALID:Specifies whether the procedure is valid or not. This becomes 'FALSE' when its base objects are changed or dropped: 'TRUE'/ 'FALSE'

    IS_HEADER_ONLY:Specifies whether the procedure is header-only procedure or not: 'TRUE'/'FALSE'

    HAS_TRANSACTION_CONTROL_STATEMENTS:Specifies whether the procedure has transaction control statements or not:'TRUE'/'FALSE'

    OWNER_NAME:Name of the owner of the procedure

    TABLE:SYS.PROCEDURE_PARAMETERS

    procedure的参数信息

    SCHEMA_NAME:Schema name of the stored procedure

    PROCEDURE_NAME:Name of the stored procedure

    PROCEDURE_OID:Object ID of the stored procedure

    PARAMETER_NAME:Parameter name

    DATA_TYPE_ID:Data type ID

    DATA_TYPE_NAME: Data type name

    LENGTH: Parameter length

    SCALE:Scale of the parameter

    POSITION :Ordinal position of the parameter

    TABLE_TYPE_SCHEMA:Schema name of table type if DATA_TYPE_NAME is TABLE_TYPE

    TABLE_TYPE_NAME: Name of table type if DATA_TYPE_NAME is TABLE_TYPE IS_INPLACE_TYPE VARCHER(5) Specifies whether the tabular parameter type is an inplace table type: 'TRUE'/'FALSE'

    PARAMETER_TYPE: Parameter mode: 'IN', 'OUT', 'INOUT'

    HAS_DEFAULT_VALUE:Specifies whether the parameter has a default value or not: 'TRUE', 'FALSE'

    IS_NULLABLE:Specifies whether the parameter accepts a null value: 'TRUE', 'FALSE'

    TABLE:SYS.OBJECT_DEPENDENCIES

    对象之间的依赖关系,例如,引用特定表的视图

    BASE_SCHEMA_NAME : Schema name of the base object

    BASE_OBJECT_NAME : Object name of the base object

    BASE_OBJECT_TYPE : Type of the base object

    DEPENDENT_SCHEMA_NAME : Schema name of the dependent object

    DEPENDENT_OBJECT_NAME : Object name of the dependent object

    DEPENDENT_OBJECT_TYPE : Type of the base dependent

    DEPENDENCY_TYPE :ype of dependency between base and dependent object.

    Possible values are:

    0: NORMAL (default)

    1: EXTERNAL_DIRECT (direct dependency between dependent object and base object)

    2: EXTERNAL_INDIRECT (indirect dependency between dependent object und base object)

    5: REFERENTIAL_DIRECT (foreign key dependency between tables)

    TABLE:PROCEDURE_PARAMETER_COLUMNS

    显示procedure中定义的参数

    SCHEMA_NAME:Schema name of the procedure

    PROCEDURE_NAME:Name of the procedure

    PROCEDURE_OID:Object ID of the procedure

    PARAMETER_NAME:Parameter name

    PARAMETER_POSITION : Ordinal position of the parameter

    COLUMN_NAME : Name of the column of the parameter type

    POSITION : Ordinal position of the column in a record

    DATA_TYPE_NAME :SQL data type name of the column

    LENGTH : Number of chars for char types, number of max digits for numeric types; number of chars for datetime types, number of bytes for LOB types

    SCALE :Numeric types: the maximum number of digits to the right of the decimal point; time, timestamp: the decimal digits are defined as the number of digits to the right of the decimal point in the second's component of the data

    IS_NULLABLE :Specifies whether the column is allowed to accept null value: 'TRUE'/'FALSE'

    */

    SELECT * FROM SYS.PROCEDURES WHERE PROCEDURE_NAME = 'TEST_PROC2';
    SELECT * FROM SYS. PROCEDURE_PARAMETERS WHERE PROCEDURE_NAME = 'TEST_PROC2';
    
    /*依赖procedure创建*/
    CREATE PROCEDURE test_proc_dep(IN a INTEGER,IN b INTEGER)
           LANGUAGE SQLSCRIPT AS
    BEGIN
           SELECT a+b AS "sum" FROM DUMMY;
    END;
    
    CREATE PROCEDURE test_proc_dep1()
           LANGUAGE SQLSCRIPT AS
    BEGIN
           CALL test_proc_dep(10,100);
    END;
    SELECT * FROM SYS.OBJECT_DEPENDENCIES WHERE DEPENDENT_OBJECT_NAME = 'TEST_PROC_DEP';
    
    SELECT * FROM PROCEDURE_PARAMETER_COLUMNS WHERE PARAMETER_NAME = 'INTAB';

    3.2 User-Defined Function

    /*

    2.2 User-Defined Function

    两种类型:

     Table User-Defined Functions

     Scalar UserDefined Functions

    差异比较:

    1.Functions Calling

    A table UDF can only be called in the FROM-clause of an SQL statement in the same parameter positions as table names.

    For example, SELECT  * FROM myTableUDF(1)

    A Scalar UDF can be called in SQL statements in the same parameter positions as table column names.

    That takes place in the SELECT and WHERE clauses of SQL statements.

    For example, SELECT myScalarUDF(1) AS myColumn FROM DUMMY

    2.Input Parameter (输入类型参数)

    table UDF:

    Primitive SQL type

    Table types

    Scalar UDF:

    Primitive SQL type

    Table types (with limitations)

    3.Output

    table UDF:

    Must return a table whose type is defined in <return_type>.

    Scalar UDF:

    Must return scalar values specified in <return_parameter_list>.

    4.Supported functionality

    table UDF:

    The function is tagged as read only by default.

    DDL and DML are not allowed and only other read-only functions can be called.

    Scalar UDF:

    The function is tagged as a read-only function by default.

    */

    /*

    2.2.1 创建Function

    语法:

    CREATE [OR REPLACE] FUNCTION <func_name> [(<parameter_clause>)] RETURNS <return_type>

     [LANGUAGE <lang>]

     [SQL SECURITY <mode>]

     [DEFAULT SCHEMA <default_schema_name>

     [DETERMINISTIC]]

     [WITH ENCRYPTION] AS

     BEGIN   

           <function_body>

     END

    <func_name > ::= [<schema_name>.]<identifier>

    <parameter_clause> ::= <parameter> [{,<parameter>}...]

    <parameter> ::= [IN] <param_name> <param_type>

    <param_type> ::= <sql_type> [ARRAY] | <table_type> | <table_type_definition> | <any_table_type>

    <sql_type> ::= DATE | TIME | TIMESTAMP | SECONDDATE | TINYINT | SMALLINT | INTEGER | BIGINT

           | DECIMAL | SMALLDECIMAL | REAL | DOUBLE | VARCHAR | NVARCHAR

           | VARBINARY | CLOB | NCLOB | BLOB | ST_GEOMETRY| ARRAY

    <table_type> ::= <identifier>

    Scalar UDF可以使用<sql_type>,<table_type>,Array可以作为input,return参数。

    SUDFs with table parameters can be used like any other SUDF with following exceptions:

    1.Aliases (in FROM or WITH clauses) are not allowed.

    2.Parameterized views, scripted calculation views or TUDFs as input are not supported.

    3.ANY TABLE TYPE parameters are not supported.

    4.SQLScript internal types, such as cursor variables or ROW types, are not supported.

    Table UDF可以使用<sql_type>,<table_type>,Array

    <table_type_definition>    ::=  TABLE (<column_list_definition>)

    <column_list_definition > ::= <column_elem>[{, <column_elem>}...]

    <column_elem> ::= <column_name> <data_type>

    <column_name> ::= <identifier>

    <return_type> ::= <return_parameter_list> | <return_table_type>

    Scalar UDF返回值:

    <return_parameter_list> ::= <return_parameter>[{, <return_parameter>}...]

    <return_parameter>      ::= <parameter_name> <sql_type> [ARRAY]

    Table UDF返回table:

    <return_table_type> ::= TABLE ( <column_list_definition> )

    设置语言

    LANGUAGE <lang>

    <lang> ::= SQLSCRIPT

    设置安全模式

    SQL SECURITY <mode>

    <mode> ::= DEFINER | INVOKER

    设置默认schema

    DEFAULT SCHEMA <default_schema_name>

    <default_schema_name> ::= <unicode_name>

    <function_body>  ::= <scalar_function_body>|<table_function_body>

    <scalar_function_body> ::= [DECLARE <func_var>] <proc_assign>

    <table_function_body>  ::= [<func_block_decl_list>] [<func_handler_list>] <func_stmt_list> <func_return_statement>

    <func_block_decl_list> ::= DECLARE { <func_var>|<func_cursor>|<func_condition> }

    <func_var>::= <variable_name_list> [CONSTANT] { <sql_type>| <array_datatype> } [NOT NULL][<func_default>];

    <array_datatype>       ::= <sql_type> ARRAY [ = <array_constructor> ]

    <array_constructor>    ::= ARRAY ( <expression> [{,<expression>}...] )

    <func_default>         ::= { DEFAULT | = } <func_expr>

    <func_expr>            ::= !!An element of the type specified by <sql_type>

    <func_handler_list> ::= <proc_handler_list>

    <func_stmt_list> ::= <func_stmt>| <func_stmt_list> <func_stmt>

    <func_stmt>      ::= <proc_block>                    

           | <proc_assign> | <proc_single_assign>                   

           | <proc_if>     | <proc_while>                   

           | <proc_for>    | <proc_foreach>                   

           | <proc_exit>   | <proc_signal>                   

           | <proc_resignal> | <proc_open>    

           | <proc_fetch>  | <proc_close>         

    <func_return_statement> ::= RETURN <function_return_expr>

    <func_return_expr>      ::= <table_variable> | <subquery>

    A table function must contain a return statement.

    必须要有return语句

    */

    --创建a table function
    --返回table
    CREATE FUNCTION scale (val INT)
      RETURNS TABLE (a NVARCHAR(20), b INT)
      LANGUAGE SQLSCRIPT AS
    BEGIN   
      RETURN SELECT "Product_Name" as a, :val * "Quantity" AS  b FROM "MyProducts";
    END;
    
    --调用table function
    SELECT * FROM scale(10);
    SELECT * FROM scale(10) AS a,scale(20) as b where a.a = b.a;
    
    --创建a scalar function
    --返回两个值的和,乘积
    CREATE FUNCTION func_add_mul(x Double, y Double)
      RETURNS result_add Double, result_mul Double 
      LANGUAGE SQLSCRIPT READS SQL DATA AS
    BEGIN    
      result_add = :x + :y;    
      result_mul = :x * :y;
    END;
    
    --调用scalar function
    SELECT "Product_ID","Quantity","Price",func_add_mul("Quantity","Price").result_mul AS "Payment" FROM "MyProducts";
    
    --可以在其他scalar function中调用function
    CREATE FUNCTION func_multipy(x Double,y Double)
      RETURNS output1 double
      LANGUAGE SQLSCRIPT  AS
    BEGIN   
           output1 = func_add_mul(:x,:y).result_add * func_add_mul(:x,:y).result_mul;
    END;  
    --调用function
    SELECT func_multipy(2,2) as RESULT FROM dummy;

    /*

    2.2.2 修改function

    ALTER FUNCTION <func_name>

     RETURNS <return_type>

     [LANGUAGE <lang>]

     [DEFAULT SCHEMA <default_schema_name>] AS

    BEGIN 

           <function_body>

    END

    */

    --获取function
    CREATE FUNCTION GET_FUNCTIONS
     RETURNS TABLE(schema_name NVARCHAR(256), name NVARCHAR(256))                                                    
     AS
    BEGIN     
     RETURN SELECT schema_name AS schema_name,function_name AS name FROM FUNCTIONS;
    END;
    
    --调用function
    SELECT * FROM GET_FUNCTIONS();
    
    --修改function
    ALTER FUNCTION GET_FUNCTIONS
     RETURNS TABLE(schema_name NVARCHAR(256), name NVARCHAR(256))                                                   
     AS
    BEGIN     
     RETURN SELECT schema_name AS schema_name,function_name AS name FROM FUNCTIONS WHERE IS_VALID = 'TRUE';
    END;

    /*

    2.2.3删除function

    DROP FUNCTION <func_name> [<drop_option>]

    <func_name> ::= [<schema_name>.]<identifier>

    <drop_option> ::= CASCADE | RESTRICT

    如果没有指定<drop_option>,执行non-cascade删除,只删除指定function,依赖function将失效;

    cascade:级连删除;

    restrict:删除function不能有依赖function,如果有报错;

    */

    DROP FUNCTION GET_FUNCTIONS;

    /*

    2.2.4 function参数

    Table user-defined functions

           Can have a list of input parameters and must return a table whose type is defined in <return type>

           Input parameters must be explicitly typed and can have any of the primitive SQL type or a table type.

    Scalar user-defined functions

           Can have a list of input parameters and must returns scalar values specified in <return parameter list>.

           Input parameters must be explicitly typed and can have any primitive SQL type.

           Using a table as an input is not allowed.

    */

    /*

    2.2.5 Consistent Scalar Function Result

    procedure中调用function,保持数据一致性。

    */

    CREATE TABLE test_consistent(C1 VARCHAR(20));
    CREATE FUNCTION func_count RETURNS v_result INTEGER AS
    BEGIN  
           SELECT COUNT(*) INTO v_result FROM test_consistent;
    END;
    
    CREATE PROCEDURE proc_insert_delete AS
    BEGIN   
           INSERT INTO test_consistent VALUES ('test');   
           SELECT 'TRACE 1: COUNT AFTER INSERT', COUNT(*) FROM test_consistent;   
           SELECT 'TRACE 2: COUNT DURING FUNCTION CALL', func_count() FROM DUMMY;   
           DELETE FROM test_consistent;   
           SELECT 'TRACE 3: COUNT AFTER DELETE', COUNT(*) FROM test_consistent;   
           COMMIT;
    END;
    
    --调用procedure
    CALL proc_insert_delete;

    /*

    2.2.6 Function Metadata

    SYS.FUNCTIONS:系统可用function;

    SCHEMA_NAME:NVARCHAR(256) Schema name of the function

    FUNCTION_NAME:NVARCHAR(256) Name of the function

    FUNCTION_OID:BIGINT Object ID of the function

    SQL_SECURITY:VARCHAR(7) SQL Security setting of the function:'DEFINER'/'INVOKER'

    DEFAULT_SCHEMA_NAME:NVARCHAR(256) Schema name of the unqualified objects in the function

    INPUT_PARAMETER_COUNT:INTEGER Input type parameter count

    RETURN_VALUE_COUNT:INTEGER Return value type parameter count

    IS_UNICODE:VARCHAR(5) Specifies whether the function contains Unicode or not: 'TRUE', 'FALSE'

    DEFINITION:NCLOB Query string of the function

    FUNCTION_TYPE:VARCHAR(10) Type of the function

    FUNCTION_USAGE_TYPE:VARCHAR(9) Usage type of the function:'SCALAR', 'TABLE', 'AGGREGATE','WINDOW'

    IS_VALID:VARCHAR(5) Specifies whether the function is valid or not. This becomes 'FALSE' when its base objects are changed or dropped: 'TRUE', 'FALSE'

    IS_HEADER_ONLY:VARCHAR(5) Specifies whether the function is header-only function or not: 'TRUE'/'FALSE'

    OWNER_NAME:NVARCHAR(256) Name of the owner of the function

    SYS.FUNCTION_PARAMETERS:function的参数表

    SCHEMA_NAME: NVARCHAR(256) Schema name of the function

    FUNCTION_NAME: NVARCHAR(256) Name of the function

    FUNCTION_OID: BIGINT Object ID of the function

    PARAMETER_NAME: NVARCHAR(256) Parameter name

    DATA_TYPE_ID: INTEGER Data type ID

    DATA_TYPE_NAME: VARCHAR(16) Data type name

    LENGTH: INTEGER Parameter length

    SCALE: INTEGER Scale of the parameter

    POSITION: INTEGER Ordinal position of the parameter

    TABLE_TYPE_SCHEMA: NVARCHAR(256) Schema name of table type if DATA_TYPE_NAME is TABLE_TYPE

    TABLE_TYPE_NAME: NVARCHAR(256) Name of table type if DATA_TYPE_NAME is TABLE_TYPE

    IS_INPLACE_TYPE: VARCHAR(5) Specifies whether the tabular parameter type is an inplace table type: 'TRUE'/'FALSE'

    PARAMETER_TYPE: VARCHAR(7) Parameter mode: IN, OUT, INOUT

    HAS_DEFAULT_VALUE: VARCHAR(5) Specifies whether the parameter has a default value or not: 'TRUE', 'FALSE'

    IS_NULLABLE: VARCHAR(5) Specifies whether the parameter accepts a null value: 'TRUE', 'FALSE'

    FUNCTION_PARAMETER_COLUMNS:正在使用的table type

    SCHEMA_NAME: NVARCHAR(256) Schema name of the function

    FUNCTION_NAME: NVARCHAR(256) Name of the function

    FUNCTION_OID: BIGINT Object ID of the function

    PARAMETER_NAME: NVARCHAR(256) Parameter name

    PARAMETER_POSITION: INTEGER Ordinal position of the parameter

    COLUMN_NAME: NVARCHAR(256) Name of the column in the table parameter

    POSITION: INTEGER Ordinal position of the column in the table parameter

    DATA_TYPE_NAME: VARCHAR(16) SQL data type name of the column

    LENGTH: INTEGER Number of chars for char types, number of max digits for numeric types; number of chars for datetime types, number of bytes for LOB types

    SCALE INTEGER: Numeric types: the maximum number of digits to the right of the decimal point; time, timestamp: the decimal digits are defined as the number of digits to the right of the decimal point in the second's component of the data

    IS_NULLABLE: VARCHAR(5) Specifies whether the column is allowed to accept null values: 'TRUE'/'FALSE'

    设置function参数默认值

    IN <param_name>  (<sql_type>|<table_type>|<table_type_definition>) DEFAULT (<value>|<table_name>)

    */

    SELECT * FROM FUNCTIONS;
    --
    SELECT * FROM FUNCTION_PARAMETERS;
    --
    SELECT * FROM FUNCTION_PARAMETER_COLUMNS;
    
    --设置默认值,默认输入参数,table类型
    CREATE TABLE TEST_DEFAULT( s_type VARCHAR(10),s_name VARCHAR(20) );
    INSERT INTO TEST_DEFAULT VALUES('type1','tom');
    INSERT INTO TEST_DEFAULT VALUES('type2','jon');
    CREATE FUNCTION func_default_value(
           IN INTAB TABLE(s_type VARCHAR (10), s_name VARCHAR (20)) DEFAULT "TEST_DEFAULT",
           IN delimiter VARCHAR(10) DEFAULT ':')
           RETURNS TABLE(fullstring VARCHAR(40)) AS
    BEGIN   
           RETURN SELECT s_type||:delimiter||s_name AS fullstring FROM :INTAB;    
    END;
    
    --调用function
    SELECT * FROM func_default_value();
    
    --不使用默认值
    SELECT * FROM func_default_value(delimiter=>',');

    /*

    2.2.7 SQL嵌入function

    */

    --SQL语句使用table function
    CREATE FUNCTION TEMP_FUNC()
     RETURNS TABLE (A INT, B INT, C INT) AS
     BEGIN      
          DECLARE buffer TABLE (A INT, B INT, C INT);       
          :buffer.insert(( 1, 2, 3));       
          :buffer.insert(( 1, 2, 4));       
          :buffer.insert(( 2, 3, 2));       
          :buffer.insert(( 2, 3, 4));       
          :buffer.insert(( 2, 5, 7));       
          RETURN :buffer;
     END;
    
    SELECT A, B, SUM(C) FROM TEMP_FUNC()
           GROUP BY A, B
           ORDER BY A, B;
    --SQL嵌入table function
    SELECT A, B, SUM(C) FROM
           SQL FUNCTION       
                 RETURNS TABLE (A INT, B INT, C INT)       
           BEGIN              
                  DECLARE buffer TABLE (A INT, B INT, C INT);              
                  :buffer.i nsert((1, 2, 3));              
                  :buffer.i nsert((1, 2, 4));             
                  :buffer.i nsert((2, 3, 2));              
                  :buffer.i nsert((2, 3, 4));              
                  :buffer.i nsert((2, 5, 7));              
                  RETURN :buffer;       
           END
           GROUP BY A, B
           ORDER BY A, B;
    
    -- input parameter
    SELECT a FROM 
           SQL FUNCTION (IN a INT => 1) 
        RETURNS TABLE(a INT) 
        BEGIN  
               RETURN SELECT :a AS a FROM dummy; 
        END;
    
    -- nested SQL FUNCTION clause
    SELECT a FROM SQL FUNCTION
           RETURNS TABLE (a int) 
           BEGIN  
                  RETURN SELECT * FROM SQL FUNCTION   
                         RETURNS TABLE (a int)     
                         BEGIN       
                           RETURN SELECT 1 AS a FROM dummy;     
                         END;
           END;

    /*

    2.2.8 Deterministic Scalar Functions

    Deterministic Scalar Functions相同条件总是返回确定值

    2.2.9 Procedure Result Cache

    PRC:过程结果缓存,以输入参数作为key,输出参数作为值;

    注意:PRC is enabled only for deterministic procedures

    */

    --创建deterministic function
    --deterministic??不支持
    
    /*
    CREATE FUNCTION func_deterministic(IN a INT)
     RETURNS ret INT deterministic AS
     BEGIN
          ret = :a;
     END;
    SELECT func_deterministic("A") FROM "TEST";
    */

    --创建deterministic procedure
    --deterministic??不支持
    /*
    create procedure add (in a int, in b int, out c int) deterministic as
    begin
           c = :a + :b;
    end
    */

    3.3 User-Defined Libraries

    /*

    2.3 User-Defined Libraries

    定义一组variable、procedures,functions;

    创建Library

    CREATE [OR REPLACE] LIBRARY <lib_name>

     [LANGUAGE SQLSCRIPT] [DEFAULT SCHEMA <default_schema_name>] AS

     BEGIN 

           [<lib_var_decl_list>]  [<lib_proc_func_list>]

     END;

    修改Library

    ALTER LIBRARY <lib_name>

     [LANGUAGE SQLSCRIPT] [DEFAULT SCHEMA <default_schema_name>] AS

     BEGIN 

           [<lib_var_decl_list>]  [<lib_proc_func_list>]

     END;

    删除Library

    DROP LIBRARY <lib_name>;

    <lib_name> ::= [<schema_name>.]<identifier>;

    <lib_var_decl_list> ::= <lib_var_decl> [{<lib_var_decl>}...]

    <lib_var_decl> ::= <access_mode> <var_decl> ;

    <var_decl> ::= VARIABLE <member_name> [CONSTANT] <sql_type> [NOT NULL] [<proc_default>]

    <access_mode> ::= PUBLIC | PRIVATE <member_name> ::= <identifier>

    <proc_default> ::= { DEFAULT | '=' } <expression>

    <lib_proc_func_list> ::= <lib_proc_func> [{<lib_proc_func>}...]

    <lib_proc_func> ::= <access_mode> <proc_func_def> ;

    <proc_func_def> ::= <proc_def> | <func_def>

    <proc_def> ::= PROCEDURE <member_name> [<parameter_clause>] [<proc_property>] AS

           BEGIN

               [SEQUENTIAL EXECUTION] <procedure_body>

          END

    <proc_property> ::= [LANGUAGE <lang>] [SQL SECURITY <mode>] [READS SQL DATA]

    <func_def> ::= FUNCTION <member_name> [<parameter_clause>] RETURNS <return_type> [<func_property>] AS

           BEGIN

                  <function_body>

           END

    <func_property> ::= [LANGUAGE <lang>] [SQL SECURITY <mode>] [READS SQL DATA]

    两种类型Library:built-in libraries:系统提供;

                          user-defined libraries:用户定义;

    Library仅可以使用在Procedures,functions.

    Library Members:

    <procedure_body> ::= [<proc_using_list>] [<proc_handle_list>] <proc_stmt_list>

    <proc_using_list> ::= {<proc_using>}...

    <proc_using> ::= USING <lib_name> AS <lib_alias> ;

    <lib_name> ::= [<schema_name>.]<identifier>

    <lib_alias> ::= <identifier>

    <lib_member_ref> ::= [ <schema_name> . ] <identifier> ':' <member_name>

    <proc_assign> ::= <variable_name> = { <expression> | <array_function> | <lib_member_func_call>} ;                

           | <variable_name> '[' <expression> ']' = { <expression> | <lib_member_func_call> } ;               

           | <lib_member_ref> = { <expression> | <lib_member_func_call> } ;

    <lib_member_func_call> ::= <lib_member_ref> ( [<expression> [ {, <expression> }...] ] )

    <proc_call> ::= CALL <proc_name> ( <param_list> ) ;

                   | CALL <lib_member_ref> ( <param_list> ) ;

    LIBRARIES

    所有有效的Libraries

    SCHEMA_NAME: Schema name of the library

    LIBRARY_NAME: Name of the library

    LIBRARY_OID: Object ID of the library

    OWNER_NAME: Owner name of the library

    DEFAULT_SCHEMA_NAME: Schema of the unqualified objects in the library

    DEFINITION: Definition of the library

    LIBRARY_TYPE: Language type of the library

    IS_VALID: Specifies whether the library is valid or not. This becomes false when its base objects are changed or dropped.

    CREATE_TIME: Creation time

    LIBRARY_MEMBERS

    Library members信息

    SCHEMA_NAME: Schema name of the library

    LIBRARY_NAME: Name of the library

    LIBRARY_OID: Object ID of the library

    MEMBER_NAME: Name of the library member

    MEMBER_TYPE: Type of the library member: 'VARIABLE', 'PROCEDURE', 'FUNCTION'

    ACCESS_MODE: Access mode of the library member: 'PUBLIC', 'PRIVATE'

    DEFINITION: Definition string of the library member

    UDL Member Procedure Call Without SQLScript Artifacts

    <call_stmt> ::= CALL <proc_name> ( <param_list> ) [WITH OVERVIEW] [IN DEBUG MODE]

                   | CALL <lib_member_ref> ( <param_list> );

    <proc_call> ::= CALL <proc_name> ( <param_list> ) ;             

                            | CALL <lib_member_ref> ( <param_list> ) ;

    <lib_member_ref> ::= [<schema_name> '.'] <library_name_or_alias> ':' <member_name>

    <schema_name> ::= <identifier>

    <library_name_or_alias> ::= <identifier>

    <member_name> ::= <identifier>

    Library Member Functions and Variables

    Library member functions and variables can be used directly in SQL or expressions in SQLScript.

    可以直接在SQL中使用

    <expression> ::= <case_expression> | <function_expression> | ... | <variable_name> | ...

    <function_expression> ::= <function_name> ( <expression> [{, <expression} ...])

    <function_name> ::= [[ <database_name> '.' ] <schema_name> '.' ]] <identifier> | <lib_member_ref>

    <variable_name> ::= <identifier> | <lib_member_ref>

    <from_clause> ::= FROM <table_expression> [, <table_expression> ...]

    <table_expression> ::= <table_ref> | ... | <function_reference> | ...

    <function_reference> ::= <function_name> ( <proc_arg_list> | <opt_parameter_key_value_list> )

    <lib_member_ref> ::= [<schema_name> '.' ] <library_name_or_alias> ':' <member_name>

    <schema_name> ::= <identifier>

    <library_name_or_alias> ::= <identifier>

    <member_name> ::= <identifier>

    */

    /*--创建Library*/
    --for 语句创建表插入数据
    create table test_data_table(col1 int);
    do begin 
          declare idx int = 0; 
          for idx in 1..200 do   
                 insert into test_data_table values (:idx); 
          end for;
    end;
    
    --创建library
    create LIBRARY lib_test1 as begin
           public variable maxval constant int = 100;
           public function bound_with_maxval(i int) returns x int as begin   
                  x = case when :i > :maxval then :maxval else :i end; 
         end;
           public procedure get_data(in size int, out result table(col1 int)) as begin   
                  result = select top :size col1 from test_data_table; 
         end;
    end;
    
    --procedure使用library
    create procedure proc_test1 (in inval int) as
    begin
       using lib_test1 as mylib; 
       declare var1 int = mylib:bound_with_maxval(:inval);
       if :var1 > mylib:maxval then   
         select 'unexpected' from dummy; 
       else   
         declare tv table (col1 int);   
         call mylib:get_data(:var1, tv);   
         select count(*) from :tv; 
       end if;
    end;
    
     
    /*Libraries相关信息*/
    --LIBRARIES信息
    SELECT * FROM LIBRARIES;
    --不存在?
    SELECT * FROM LIBRARY_MEMBERS;
    
    /*UDL Member Procedure Call Without SQLScript Artifacts*/
    --调用library时,必须在匿名block或者procedure,function中,现在可以直接调用
    create library mylib as begin
       public procedure memberproc(in i int, out tv table(col1 nvarchar(10))) as begin   
         tv = select :i * 100 as col1 from dummy; 
         end;
    end;
    
    do (in iv int => 1, out otv table(col1 nvarchar(10)) => ?) begin  using mylib as mylib;
           call mylib:memberproc(:iv, otv);
    end;
    
    --直接调用library
    create library mylib as begin
       public procedure memberproc(in i int, out tv table(col1 nvarchar(10))) as begin   
         tv = select :i * 100 as col1 from dummy; 
       end;
    end;
    call mylib:memberproc(1, ?);
    
     
    /*Library Member Functions and Variables*/
    --创建表插入数据
    create table test_r_tab (r decimal);
    insert into test_r_tab values (50);
    insert into test_r_tab values (100);
    
    --创建library
    create library lib_test2 as begin 
           public variable pi constant decimal = 3.14; 
           public function circumference(r decimal) returns a int as begin   
                  a = 2 * :pi * :r;
           end; 
           public function circumference_table(r_table table(r decimal)) returns table(c decimal) as begin   
                  return select 2 * :pi * r as c from :r_table; 
           end;
     end;
    
     --直接SQL调用
    select lib_test2:circumference(10) from dummy;

    3.4 Create or Replace

              当创建Function,Procedure时,使用OR REPLACE创建或者替换Function, Procedure。

    示例:

    /*

    2.4CREATE OR REPLACE

    创建Function,Procedure时,使用OR REPLACE修改function,procedure.

    CREATE [OR REPLACE] FUNCTION <function_name>

    [(<parameter_clause>)]

    RETURNS <return_type>

    [LANGUAGE <lang>]

    [SQL SECURITY <mode>]

    [DEFAULT SCHEMA <default_schema_name>]

    [DETERMINISTIC]

    [WITH ENCRYPTION] AS

    { BEGIN <function_body> END | HEADER ONLY }

    [WITH [<cache_type>]

    CACHE RETENTION <minute_value>

    [OF <projection_list>]

    [FILTER <filter_condition>]]

    CREATE [OR REPLACE] PROCEDURE <procedure_name>

    [(<parameter_clause>)]

    [LANGUAGE <lang>]

    [SQL SECURITY <mode>]

    [DEFAULT SCHEMA <default_schema_name>]

    [{ ROUTE TO REMOTE SOURCE <name_list>

        | ROUTE TO VOLUME <volume_id_list>

        | ROUTE BY TABLE <hint_table_list> }]

    [DETERMINISTIC] [WITH ENCRYPTION] AS

    { BEGIN <procedure_body> END | HEADER ONLY

    "测试时环境不支持,OR REPLACE

    */

    CREATE PROCEDURE test_proc5 as
    begin  
        select * from dummy;
    end;
    call test_proc5();
    
    --报错:number of parameters cannot be changed with ALTER command
    --可以更改<body>中内容
    ALTER PROCEDURE test_proc5() as
    begin   
        select 1 from dummy;   
    end;
    call test_proc5();
    
    --replace procedure
    -- new parameter
    -- add default parameter value
    -- change the number of parameter and name of parameter
    --?报错,不支持CREATE OR REPLACE
    CREATE OR REPLACE PROCEDURE test_proc5(IN a INT) as
    begin  
        select a from dummy;
    end;
    call test_proc5(1);

    3.5 Anonymous Block

           创建匿名代码块

    示例:

    /*

    2.5Anonymous Block

    匿名代码块

    语法:

    DO [(<parameter_clause>)]

    BEGIN [SEQUENTIAL EXECUTION]   

        <body>

    END WITH HINT (...)

    <body>内容和procedure中一致

    <parameter_clause> ::=  <named_parameter> [{,<named_parameter>}...]

    <named_parameter>  ::= (IN|OUT) <param_name> <param_type> => <proc_param>

    */

    DO (IN in_var NVARCHAR(20)=> 'P1',OUT outtab TABLE (A NVARCHAR(20),B NVARCHAR(20)) => ?)
    BEGIN   
        T1 = SELECT "Product_ID" AS A,"Product_Name" AS B  FROM "MyProducts" WHERE "Product_ID" = in_var;      
        outtab = SELECT * FROM :T1;   
    END
    
    --block with hint
    --报错不支持
    DO BEGIN
       DECLARE i INT; 
       FOR i in 1..5 DO   
         SELECT * FROM dummy;
       END FOR;
    END WITH HINT(dev_se_use_llvm)
    
    --block创建table,插入数据
    DO BEGIN   
        DECLARE I INTEGER;   
        CREATE TABLE MYTAB4(I INTEGER);    
        FOR I IN 1..10 DO       
             INSERT INTO MYTAB4 VALUES (:I);   
        END FOR;
    END

    3.6 SQLScript Encryption

    示例:

    /*

    2.6 SQLScript Encryption

    定义时使用[WITH ENCRYPTION]

    [CREATE | ALTER] PROCEDURE <proc_name> [(<parameter_clause>)]

    [LANGUAGE <lang>]

    [SQL SECURITY <mode>]

    [DEFAULT SCHEMA  <default_schema_name>]

    [READS SQL DATA ] 

    [<sqlscript_route_option>] 

    [WITH ENCRYPTION]

    AS BEGIN  ... END;

    [CREATE | ALTER] FUNCTION <func_name> [(<parameter_clause>)] RETURNS <return_type>

    [LANGUAGE <lang>]

    [SQL SECURITY <mode>]

    [DEFAULT SCHEMA <default_schema_name>]

    [READS SQL DATA] 

    [<sqlscript_route_option>]

    [DETERMINISTIC] 

    [WITH ENCRYPTION]

    AS BEGIN  ... END;

    "已经创建的Procedure,function,设置加密

    ALTER PROCEDURE <proc_name> ENCRYPTION ON;

    ALTER FUNCTION <func_name> ENCRYPTION ON;

    */

    --没有IS_ENCRYPTED列
    SELECT * FROM  PROCEDURES;
    SELECT * FROM FUNCTIONS;
    
    --?with encryption报错
    create procedure test_encry_proc with encryption as
    begin 
     select 1 as i from dummy;
    end;
  • 相关阅读:
    阶乘
    如何利用”七牛云”在UEditor实现图片的上传和浏览
    ueditor保存出现 从客户端(Note="<p>12345</p>")中检测到有潜在危险的 Request.Form 值
    配置进程外的Session
    数据库增加索引
    判断HTML中的checkbox是否被选中
    Oracle 配置文件目录
    Oracle 游标
    Oracle 分区表的索引、分区索引
    Oracle 索引
  • 原文地址:https://www.cnblogs.com/tangToms/p/14111019.html
Copyright © 2020-2023  润新知