精华内容
下载资源
问答
  • MySQL 存储过程参数

    2021-02-08 06:55:29
    MySQL 存储过程参数MySQL存储过程参数简介在现实应用中,开发的存储过程几乎都需要参数。这些参数使存储过程更加灵活和有用。 在MySQL中,参数有三种模式:IN,OUT或INOUT。IN- 是默认模式。在存储过程中定义IN参数...

    MySQL  存储过程参数

    MySQL存储过程参数简介

    在现实应用中,开发的存储过程几乎都需要参数。这些参数使存储过程更加灵活和有用。 在MySQL中,参数有三种模式:IN,OUT或INOUT。

    IN - 是默认模式。在存储过程中定义IN参数时,调用程序必须将参数传递给存储过程。 另外,IN参数的值被保护。这意味着即使在存储过程中更改了IN参数的值,在存储过程结束后仍保留其原始值。换句话说,存储过程只使用IN参数的副本。

    OUT - 可以在存储过程中更改OUT参数的值,并将其更改后新值传递回调用程序。请注意,存储过程在启动时无法访问OUT参数的初始值。

    INOUT - INOUT参数是IN和OUT参数的组合。这意味着调用程序可以传递参数,并且存储过程可以修改INOUT参数并将新值传递回调用程序。

    在存储过程中定义参数的语法如下:

    MODE param_name param_type(param_size)

    上面语法说明如下 -

    根据存储过程中参数的目的,MODE可以是IN,OUT或INOUT。

    param_name是参数的名称。参数的名称必须遵循MySQL中列名的命名规则。

    在参数名之后是它的数据类型和大小。和变量一样,参数的数据类型可以是任何有效的MySQL数据类型。

    如果存储过程有多个参数,则每个参数由逗号(,)分隔。

    MySQL存储过程参数示例

    1.IN参数示例

    以下示例说明如何使用 ClassInfoProcedure 存储过程中的IN参数来查询选择相应的课程信息。

    usetest;DROP PROCEDURE IF EXISTS ClassInfoProcedure; --注意存储名不加引号。

    DELIMITER $$usetest$$CREATE PROCEDURE ClassInfoProcedure(IN id INT)BEGIN

    SELECT * FROM classInfo WHERE ids =id;END$$

    DELIMITER ;--注意这里的 ';' 前要留空格。

    id是存储过程的IN参数。在存储过程中,我们查询id参数对应的课程信息。

    假设我们想要查询id 对应的课程,我们只需要将一个值(id)传递给存储过程,如下所示:

    CALL ClassInfoProcedure(3);

    执行上面查询语句,得到以下结果

    bb1fe7fc6f875f29bc76c0ac24ee2bed.png

    2.OUT参数示例

    以下存储过程通过订单状态返回订单数量。它有两个参数:

    orderStatus:IN参数,它是要对订单计数的订单状态。

    total:存储指定订单状态的订单数量的OUT参数。

    以下是CountOrderByStatus存储过程的源代码。

    usetest;DROP PROCEDURE IF EXISTSCountOrderByStatus;

    DELIMITER $$usetest$$CREATE PROCEDURE CountOrderByStatus(IN orderStatus VARCHAR(25),

    OUT orderCountINT)BEGIN

    SELECT count(sid) INTO orderCount FROM orderinfo WHERE order_status =orderStatus;END$$

    DELIMITER ;

    执行

    696626ea40892395809c2aa5db166c65.png

    查看客户端如下

    88fd19bdf91193ba82d4c89dcc9929da.png

    要获取发货订单的数量,我们调用CountOrderByStatus存储过程,并将订单状态传递为已收货’50’,并传递参数(

    CALL CountOrderByStatus('50',@total);SELECT @total;

    执行上面查询语句后,得到以下结果

    dd5ace06520cbcb64ca56e6167a67956.png

    注意:因为上面定义了两个参数,所以调用是也要如上 传递两个参数,如果传递一个参数,会提示如下错误。

    859d5701b48246a08e418f31c01b9487.png

    INOUT参数示例

    以下示例演示如何在存储过程中使用INOUT参数。如下查询语句

    DELIMITER $$CREATE PROCEDURE set_counter(INOUT count INT(4),IN inc INT(4))BEGIN

    SET count = count +inc;END$$

    DELIMITER ;

    上面查询语句是如何运行的?

    set_counter存储过程接受一个INOUT参数(count)和一个IN参数(inc)。

    在存储过程中,通过inc参数的值增加计数器(count)。

    下面来看看如何调用set_counter存储过程:

    c256c9b290f56069ad90f18626fec7a8.png

    SET @counter = 1;

    CALL set_counter(@counter,1); --2

    SELECT @counter; --2

    CALL set_counter(@counter,5); --7

    SELECT @counter; --7

    展开全文
  • 现在针对MSSQL中存储过程的可选参数定义和使用进行基本的介绍,留作备忘。 #准备工作: 在db_test中建立一张测试表T_test: USE db_test; CREATE TABLE dbo.T_test ( Id INT IDE可选参数的存在,可以极大的降低...

    可选参数的存在,可以极大的降低代码的重复冗余。在数据库开发中,也是如此。现在针对MSSQL中存储过程的可选参数的定义和使用进行基本的介绍,留作备忘。 #准备工作: 在db_test中建立一张测试表T_test: USE db_test; CREATE TABLE dbo.T_test ( Id INT IDE

    可选参数的存在,可以极大的降低代码的重复冗余。在数据库开发中,也是如此。现在针对MSSQL中存储过程的可选参数的定义和使用进行基本的介绍,留作备忘。

    #准备工作:

    在db_test中建立一张测试表T_test:

    USE db_test;

    CREATE TABLE dbo.T_test

    (

    Id INT

    IDENTITY(1,1)NOT NULL

    ,Name NVARCHAR(20) NOT NULL

    ,Sex BIT

    DEFAULT(0)

    );

    插入一些数据:

    INSERT INTO dbo.T_test(Name,Sex)

    VALUES(N'NAME1','1')

    ,(N'NAME2','0')

    ,(N'NAME3','1')

    ,(N'NAME4','0');

    查询测试数据:

    SELECT Id,Name,Sex

    FROM dbo.T_test;结果为:

    IdName Sex

    -------------------------------

    1NAME11

    2NAME20

    3NAME31

    4NAME40

    #存储过程

    创建一个存储过程:

    IF OBJECT_ID('dbo.up_test_get_name_by_id','P') IS NOT NULL

    DROP PROC dbo.up_test_get_name_by_id;

    GO

    CREATE PROC dbo.up_test_get_name_by_id

    @Name AS NVARCHAR(20) OUT

    ,@Id AS INT = 1  --DEFAULT VALUE: 1

    ,@Sex AS BIT = 1 --DEFAULT VALUE: 1

    AS

    BEGINSELECT @Name = Name

    FROM dbo.T_test

    WHERE  Id = @Id

    AND Sex = @Sex;

    END

    GO

    对存储过程进行调用:

    1)不传递ID和Sex

    DECLARE @Name NVARCHAR(20);

    EXEC dbo.up_test_get_name_by_id @Name OUT;

    SELECT @Name AS NAME;结果为:

    NAME

    -------------

    NAME1

    说明:

    可见,当调用存储过程的时候不传递ID,则存储过程会使用(存储过程)定义时设定的ID的默认值1,Sex默认值为1 。

    2)传递ID

    DECLARE @Name NVARCHAR(20);

    EXEC up_test_get_name_by_id @Name OUT,'3';

    SELECT @Name AS NAME;结果为:

    NAME

    -------------

    NAME3

    说明:

    当调用时传递ID,则存储过程在执行的时候会使用从外部传递进来的ID值,因为没有传递进来Sex的值,故使用Sex默认值1进行SQL查询。

    本文原创发布php中文网,转载请注明出处,感谢您的尊重!

    展开全文
  • 新问题,入参在查询REGION_USER 表时,查询出多条记录,而GION_USER表的dn是作为插入条件的,请教该怎么处理,谢谢!CREATE OR REPLACE PROCEDURE temp_jiankong1(vdblink in varchar2 )ist_A1 varchar2(100);...

    新问题,入参在查询REGION_USER 表时,查询出多条记录,而GION_USER表的dn是作为插入条件的,请教该怎么处理,谢谢!

    CREATE OR REPLACE PROCEDURE temp_jiankong1

    (vdblink in varchar2 )is

    t_A1                  varchar2(100);

    t_A2                  varchar2(100);

    t_A3                  varchar2(100);

    t_A4                  varchar2(100);

    t_A5                  varchar2(100);

    t_A6                  varchar2(100);

    t_A7                  varchar2(100);

    t_A8                  varchar2(100);

    t_A9                  varchar2(100);

    t_A10                  varchar2(100);

    t_A11                  varchar2(100);

    t_dblink               varchar2(100);

    t_day                  varchar2(100);

    t_name                 varchar2(100);

    t_dn                   varchar2(100);

    t_region               varchar2(100);

    t_vdn                   varchar2(100);

    T_IERROR VARCHAR2(300);

    T_EXISTS NUMBER;

    type t_cur is ref cursor;

    cur t_cur;

    t_sql varchar2(5000);

    BEGIN

    --execute immediate 'truncate table temp_yxf';

    t_sql:='select

    ''表空间名称'' A1,

    a.a1  A2,

    ''表空间大小M''  A3,

    round(b.b2 / 1024 / 1024,2) A4,

    ''未使用M''  A5,

    ROUND(A.a2 / 1024 / 1024,2) A6 ,

    ''已使用M'' A7,

    ROUND((b.b2 - a.a2) / 1024 / 1024,2)  A8,

    ''表空间利用率'' A9,

    ROUND((b.b2 - a.a2) / b.b2 * 100, 2)  A10,

    sysdate A11

    from (select tablespace_name a1, sum(nvl(bytes, 0)) a2

    from dba_free_space@'||vdblink||' '||

    'group by tablespace_name) a,

    (select tablespace_name b1, sum(bytes) b2

    from dba_data_files@'||vdblink||' '||

    'group by tablespace_name) b,

    (select tablespace_name c1, contents c2, extent_management c3

    from dba_tablespaces@'||vdblink||') c

    where a.a1 = b.b1

    and c.c1 = b.b1

    and a.a1 in

    (''CCATSTEP'', ''INAS'', ''INCK'', ''ODSD_DATA'', ''BDF_ATTATCH'', ''BDF_BASE'',

    ''BDF_BASE_IDX'', ''BDF_RIGHT'', ''BDF_RIGHT_IDX'', ''BDF_WORKFLOW'')' ;

    OPEN cur for t_sql;

    FETCH cur INTO t_A1,t_A2,t_A3,t_A4,t_A5,t_A6,t_A7,t_A8,t_A9,t_A10,t_A11;

    WHILE cur%FOUND LOOP

    if vdblink ='GUANGZHOU'then t_dblink :='广州';

    elsIF vdblink ='DONGGUAN'then t_dblink :='东莞';

    elsIF vdblink ='FOSHAN'then t_dblink :='佛山';

    elsIF vdblink ='YUEBEI'then t_dblink :='粤北';

    elsIF vdblink ='YUEDONG'then t_dblink :='粤东';

    elsIF vdblink ='YUEXI'then t_dblink :='粤西';

    elsIF vdblink ='ZHUSANJIAO'then t_dblink :='珠三角';

    elsIF vdblink ='SHENZHEN'then t_dblink :='深圳';

    end if;

    begin

    SELECT name,dn,region into t_name,t_dn,t_region FROM REGION_USER WHERE REGION=VDBLINK ;

    end;

    select to_char(sysdate,'day')into t_day from dual;

    IF t_A10 > '70' and t_day ='星期三'THEN

    BEGIN

    insert into ivr.Dial_Queue(serialno,areaid,businesstypeid,telephone,usertype,dealtype,content,priority,entrytime,nextdialtime,succtimes,failtimes,lockflag,locktime,batchid,dealstat,dealtimes,specialtimeflag)

    values(to_char(systimestamp, 'yyyymmddhh24missff2'),'0001','-1',t_dn,'-1','2',t_dblink||t_a2||'表空间'||t_a10||'%','101',sysdate,sysdate+1/(24*60),'0','2','0',sysdate,'0','0','2','0');

    commit;

    EXCEPTION

    WHEN OTHERS THEN

    T_IERROR := SQLCODE;

    END;

    END IF;

    FETCH cur INTO t_A1,t_A2,t_A3,t_A4,t_A5,t_A6,t_A7,t_A8,t_A9,t_A10,t_A11;

    END LOOP;

    CLOSE cur;

    COMMIT;

    END temp_jiankong1;

    展开全文
  • 文章目录 第十八章 定义和使用存储过程概述定义存储过程使用DDL定义存储过程SQL到类名转换使用类定义方法存储过程使用类定义查询存储过程自定义Query使用存储过程存储方法权限List 存储过程 第十八章 定义和使用...

    第十八章 定义和使用存储过程

    本章介绍如何在IntersystemsIRIS®数据平台上定义和使用Intersystems SQL中的存储过程。它讨论了以下内容:

    • 存储过程类型的概述
    • 如何定义存储过程
    • 如何使用存储过程如
    • 何列出存储过程及其参数。

    概述

    SQL例程是可执行的代码单元,可以由SQL查询处理器调用。 SQL例程有两种类型:功能和存储过程。从支持FunctionName()语法的任何SQL语句中调用函数。存储过程只能由CALL语句调用。函数接受某些输入定向参数并返回单个结果值。存储过程接受某些输入,输入输出和输出参数。存储过程可以是用户定义的函数,返回单个值。 CALL语句也可以调用函数。

    与大多数关系数据库系统一样,Intersystems Iris允许创建SQL存储过程。存储过程(SP)提供存储在数据库中的可调用可调用的程序,并且可以在SQL上下文中调用(例如,通过使用呼叫语句或通过ODBC或JDBC)。

    与关系数据库不同,Intersystems Iris使可以将存储过程定义为类的方法。实际上,存储过程只不过是SQL可用的类方法。在存储过程中,可以使用基于对象的全系列Intersystems的功能。

    • 可以通过查询数据库将存储过程定义为返回单个结果集数据集的查询。
    • 可以将存储过程定义为可以用作用户定义函数的函数过程,返回单个值。
    • 可以将存储过程定义为可以修改数据库数据并返回单个值或一个或多个结果集的方法。

    可以确定使用 $SYSTEM.SQL.Schema.ProcedureExists()方法是否已存在该过程。此方法还返回过程类型:“函数function”“查询query”

    定义存储过程

    与Intersystems SQL的大多数方面一样,有两种方法可以定义存储过程:使用DDL和使用类。这些在以下部分中描述。

    使用DDL定义存储过程

    Intersystems SQL支持以下命令来创建查询:

    • CREATE PROCEDURE可以创建始终作为存储过程投影的查询。
      查询可以返回单个结果集。
    • CREATE QUERY创建一个查询,该查询可以选择性地投影为存储过程。
      查询可以返回单个结果集。

    InterSystems SQL支持以下命令来创建方法或函数:

    • CREATE PROCEDURE可以创建始终作为存储过程投影的方法。
      方法可以返回单个值,也可以返回一个或多个结果集。
    • CREATE METHOD可以创建一个方法,该方法可以选择投影为存储过程。
      方法可以返回单个值,也可以返回一个或多个结果集。
    • CREATE FUNCTION可以创建一个函数过程,该函数过程可以选择投影为存储过程。
      函数可以返回单个值。

    这些命令中指定的可执行代码块可以用InterSystems SQL或ObjectScript编写。
    可以在ObjectScript代码块中包含嵌入式SQL。

    SQL到类名转换

    使用DDL创建存储过程时,指定的名称将转换为类名。
    如果类不存在,系统将创建它。

    • 如果名称是不限定的,并且没有提供FOR子句:使用系统范围的默认模式名作为包名,后跟一个点,后跟一个生成的类名,由字符串 ‘func’, ‘meth’, ‘proc’, or ‘query’组成,后跟去掉标点字符的SQL名。
      例如,未限定的过程名Store_Name会产生如下类名User.procStoreName:
      这个过程类包含方法StoreName()
    • 如果名称是限定的,并且没有提供FOR子句:模式名被转换为包名,后跟一个点,后跟字符串‘func’, ‘meth’,‘proc’, or ‘query’ ,后跟去掉标点字符的SQL名。
      如果需要,将指定的包名转换为有效的包名。

    如果名称是限定的,并且提供了FOR子句:在FOR子句中指定的限定类名将覆盖在函数、方法、过程或查询名称中指定的模式名。

    • SQL存储过程名称遵循标识符命名约定。
      InterSystems IRIS从SQL名称中去除标点字符,从而为过程类及其类方法生成唯一的类实体名称。

    下面的规则管理模式名到有效包名的转换:

    • 如果架构名称包含下划线,则此字符将转换为点,表示子包。例如,合格的名称myprocs.myname创建包myprocs。限定名称my_procs.myname创建了包含子包procs的包。

    以下示例显示了标点符号在类名和SQL调用中的不同之处。它定义了一个包含包含两个点的类名的方法。从SQL中调用时,示例将第一个点替换为下划线字符:

    Class Sample.ProcTest Extends %RegisteredObject 
     {  
        ClassMethod myfunc(dummy As %String) As %String [ SqlProc ] 
        { 
            /* method code */
            Quit "abc" 
        }
     }  
    
    SELECT Sample.ProcTest_myfunc(Name)
    FROM Sample.Person
    

    使用类定义方法存储过程

    类方法可以公开为存储过程。
    这些是不返回数据的操作的理想选择,例如计算值并将其存储在数据库中的存储过程。
    几乎所有类都可以将方法公开为存储过程;
    例外是生成器类,比如数据类型类([ClassType = datatype])。
    生成器类没有运行时上下文。
    只有在其他实体(如属性)的运行时中使用数据类型上下文才有效。

    要定义方法存储过程,只需定义一个类方法并设置其SqlProc关键字:

    Class MyApp.Person Extends %Persistent [DdlAllowed]
    {
    
        /// This procedure finds total sales for a territory
        ClassMethod FindTotal(territory As %String) As %Integer [SqlProc]
        {
            // use embedded sql to find total sales
            &sql(SELECT SUM(SalesAmount) INTO :total 
                    FROM Sales
                    WHERE Territory = :territory
            )
        
            Quit total
        }
    }
    

    编译这个类之后,FindTotal()方法将作为存储过程MyApp.Person_FindTotal()投影到SQL中。
    可以使用方法的SqlName关键字更改SQL对过程使用的名称。

    该方法使用过程上下文处理程序在过程及其调用者(例如,ODBC服务器)之间来回传递过程上下文。
    这个过程上下文处理程序是由InterSystems IRIS(作为%qHandle:%SQLProcContext)使用%sqlcontext对象自动生成的。

    %sqlcontextSQLCODE错误状态、SQL行数、错误消息等属性组成,使用相应的SQL变量设置,如下所示:

      SET %sqlcontext.%SQLCode=SQLCODE
      SET %sqlcontext.%ROWCOUNT=%ROWCOUNT
      SET %sqlcontext.%Message=%msg
    

    不需要对这些值做任何事情,但是它们的值将由客户机解释。
    在每次执行之前都会重置%sqlcontext对象。

    该方法不应该返回任何值。

    一个类的用户定义方法的最大数目是2000个。

    例如,假设有一个CalcAvgScore()方法:

    ClassMethod CalcAvgScore(firstname As %String,lastname As %String) [sqlproc]
    {
      New SQLCODE,%ROWID
      &sql(UPDATE students SET avgscore = 
        (SELECT AVG(sc.score) 
         FROM scores sc, students st
         WHERE sc.student_id=st.student_id 
           AND st.lastname=:lastname
           AND st.firstname=:firstname)
         WHERE students.lastname=:lastname
           AND students.firstname=:firstname)
    
      IF ($GET(%sqlcontext)'= "") {
        SET %sqlcontext.%SQLCODE = SQLCODE
        SET %sqlcontext.%ROWCOUNT = %ROWCOUNT
      }
      QUIT
    }
    

    使用类定义查询存储过程

    许多从数据库返回数据的存储过程可以通过标准查询接口实现。
    只要可以用嵌入式SQL编写过程,这种方法就可以很好地工作。
    注意,在以下示例中,使用了嵌入式SQL host变量为WHERE子句提供一个值:

    Class MyApp.Person Extends %Persistent [DdlAllowed]
    {
    
        /// This procedure result set is the persons in a specified Home_State, ordered by Name
        Query ListPersons(state As %String = "") As %SQLQuery [ SqlProc ]
        {
            SELECT ID,Name,Home_State
            FROM Sample.Person
            WHERE Home_State = :state
            ORDER BY Name
        }
    }
    

    要将查询公开为存储过程,可以将Studio Inspector条目中的SQLProc字段的值更改为True,或者在查询定义中添加以下“[SQLProc]”字符串:

    Query QueryName() As %SQLQuery( ... query definition ... ) 
        [ SqlProc ]
    

    编译这个类之后,ListPersons查询将作为存储过程MyApp.Person_ListPersons投影到SQL中。
    可以使用查询的SqlName关键字更改SQL用于该过程的名称。

    MyApp
    从SQL调用Person_ListPersons,它将自动返回由查询的SQL语句定义的结果集。

    下面是一个使用结果集的存储过程的示例:

    Class apc.OpiLLS.SpCollectResults1 [ Abstract ]
    {
    
    /// This SP returns a number of rows (pNumRecs) from WebService.LLSResults, and updates a property for each record
    Query MyQuery(pNumRecs As %Integer) As %Query(ROWSPEC = "Name:%String,DOB:%Date") [ SqlProc ]
    {
    }
    
    /// You put initial code here in the Execute method
    ClassMethod MyQueryExecute(ByRef qHandle As %Binary, pNumRecs As %Integer) As %Status
    {
        SET mysql="SELECT TOP ? Name,DOB FROM Sample.Person"       
        SET rset=##class(%SQL.Statement).%ExecDirect(,mysql,pNumRecs)
                IF rset.%SQLCODE'=0 {QUIT rset.%SQLCODE}
        SET qHandle=rset
        QUIT $$$OK
    }
    
    /// This code is called by the SQL framework for each row, until no more rows are returned
    ClassMethod MyQueryFetch(ByRef qHandle As %Binary, ByRef Row As %List, 
                             ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = NewQuery1Execute ]
    {
         SET rset=qHandle
         SET tSC=$$$OK 
          
         FOR {
            ///Get next row, quit if end of result set
            IF 'rset.%Next() {
                    SET Row = "", AtEnd = 1
                    SET tSC=$$$OK
                    QUIT
                    }
            SET name=rset.Name
            SET dob=rset.DOB
            SET Row = $LISTBUILD(name,dob)
            QUIT
            }         
            QUIT tSC
    }
    
    ClassMethod MyQueryClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = NewQuery1Execute ]
    {
            KILL qHandle   //probably not necesary as killed by the SQL Call framework
            QUIT $$$OK
    }
    
    }
    

    如果可以将查询编写为一个简单的SQL语句并通过查询向导创建它,那么就不需要了解实现查询的底层方法。

    在后台,对于每个查询,类编译器都会根据存储过程的名称生成方法,包括:

    • stored-procedure-nameExecute()
    • stored-procedure-nameFetch()
    • stored-procedure-nameFetchRows()
    • stored-procedure-nameGetInfo()
    • stored-procedure-nameClose()

    如果查询类型为%SQLQuery,则类编译器会自动将一些嵌入式SQL插入到生成的方法中。
    Execute()为SQL声明并打开存储的游标。
    Fetch()被反复调用,直到它返回一个空行(SET row ="")
    还可以选择让Fetch()返回一个AtEnd=1布尔标志,以表明当前获取构成最后一行,下一个获取预期返回空行。
    然而,应该总是使用空行(row ="")作为测试,以确定结果集何时结束;
    当设置AtEnd=1时,应该始终设置Row=""

    FetchRows()在逻辑上等同于反复调用Fetch()
    调用GetInfo()返回存储过程签名的详细信息。
    Close()关闭游标。

    当从客户机调用存储过程时,会自动调用所有这些方法,但理论上可以从运行在服务器上的ObjectScript直接调用这些方法。

    要将对象从Execute()传递给Fetch(),或从Fetch()传递给下一次调用Fetch(),可以将查询处理程序设置为希望传递的对象的对象引用(oref)。
    要传递多个对象,可以将qHandle设置为一个数组:

      SET qHandle(1)=oref1,qHandle(2)=oref2
    

    可以基于自定义编写的代码(而不是SQL语句)创建结果集存储过程。

    对一个类的用户定义查询Query的最大数目是200。

    自定义Query

    对于复杂的查询或不适合查询模型的存储过程,通常需要通过替换查询的部分或全部方法来自定义查询。
    你可以使用 %Library.Query

    如果选择类型%query (%Library.Query)而不是%SQLQuery (%Library.SQLQuery),则通常更容易实现查询。
    这生成了相同的5个方法,但是现在FetchRows()只是重复调用Fetch() (%SQLQuery进行了一些优化,导致了其他行为)。
    GetInfo()只是从签名中获取信息,因此代码不太可能需要更改。
    这将问题简化为为其他三个类中的每一个创建类方法。
    请注意,在编译类时,编译器会检测到这些方法的存在,而不会覆盖它们。

    这些方法需要特定的签名:它们都接受类型为%BinaryQhandle(查询处理程序)。
    这是一个指向保存查询的性质和状态的结构的指针。
    它通过引用传递给Execute()Fetch(),通过值传递给Close():

    ClassMethod SP1Close(qHandle As %Binary) As %Status
    {
       // ... 
    }
    
    ClassMethod SP1Execute(ByRef qHandle As %Binary,
        p1 As %String) As %Status
    {
       // ...
    }
    
    ClassMethod SP1Fetch(ByRef qHandle As %Binary, 
        ByRef Row As %List, ByRef AtEnd As %Integer=0) As %Status
    {
       // ...
    }
    
    Query SP1(p1 As %String) 
       As %Query(CONTAINID=0,ROWSPEC="lastname:%String") [sqlproc ]
    {
    }
    

    代码通常包括SQL游标的声明和使用。
    从类型为%SQLQuery的查询中生成的游标自动具有诸如Q14这样的名称。
    必须确保查询具有不同的名称。

    在尝试使用游标之前,类编译器必须找到游标声明。
    因此,DECLARE语句(通常在Execute中)必须与CloseFetch语句在同一个MAC例程中,并且必须出现在它们中的任何一个之前。
    直接编辑源代码,CloseFetch定义中都使用方法关键字PLACEAFTER,以确保实现这一点。

    错误消息引用内部游标名,它通常有一个额外的数字。
    因此,游标Q140的错误消息可能指向Q14

    使用存储过程

    使用存储过程有两种不同的方式:

    • 可以使用SQL CALL语句调用存储过程;
    • 可以像使用SQL查询中的内置函数一样使用存储函数(即返回单个值的基于方法的存储过程)。

    注意:当执行一个以SQL函数为参数的存储过程时,请使用CALL调用存储过程,示例如下:

    CALL sp.MyProc(CURRENT_DATE)
    

    SELECT查询不支持执行带有SQL函数参数的存储过程。
    SELECT支持执行带有SQL函数参数的存储函数。

    xDBC不支持使用SELECTCALL来执行带有SQL函数参数的存储过程。

    存储方法

    存储函数是返回单个值的基于方法的存储过程。
    例如,下面的类定义了一个存储函数Square,它返回给定值的平方:

    Class MyApp.Utils Extends %Persistent [DdlAllowed]
    {
        ClassMethod Square(val As %Integer) As %Integer [SqlProc]
        {
            Quit val * val
        }
    }
    

    存储的函数只是指定了SqlProc关键字的类方法。

    注意:对于存储的函数,ReturnResultsets关键字必须不指定(默认)或以关键字not作为开头。

    可以在SQL查询中使用存储函数,就像使用内置SQL函数一样。
    函数的名称是存储函数(在本例中为“Square”)的SQL名称,该名称由定义该函数的模式(包)名称限定(在本例中为“MyApp”)。

    下面的查询使用了Square函数:

    SELECT Cost, MyApp.Utils_Square(Cost) As SquareCost FROM Products
    

    如果在同一个包(模式)中定义了多个存储函数,则必须确保它们具有惟一的SQL名称。

    下面的示例定义了一个名为Sample的表。
    具有两个定义的数据字段(属性)和两个定义的存储函数TimePlusDTime的工资:

    Class Sample.Wages Extends %Persistent [ DdlAllowed ]
    {  
      Property Name As %String(MAXLEN = 50) [ Required ];
      Property Salary As %Integer;
      ClassMethod TimePlus(val As %Integer) As %Integer [ SqlProc ]
      {
       QUIT val * 1.5
      }
      ClassMethod DTime(val As %Integer) As %Integer [ SqlProc ]
      {
       QUIT val * 2
      }
    } 
    

    下面的查询使用这些存储过程返回同一个表Sample.Wages中每个员工的Salarytime- halfdouble time工资率:

    SELECT Name,Salary,
           Sample.Wages_TimePlus(Salary) AS Overtime,
           Sample.Wages_DTime(Salary) AS DoubleTime FROM Sample.Wages
    

    下面的查询使用这些存储过程返回不同表Sample.Employee中每个员工的Salarytime- halfdouble time工资率:

    SELECT Name,Salary,
           Sample.Wages_TimePlus(Salary) AS Overtime,
           Sample.Wages_DTime(Salary) AS DoubleTime FROM Sample.Employee
    

    权限

    要执行一个过程,用户必须具有该过程的execute权限。
    使用GRANT命令或$SYSTEM.SQL.Security.GrantPrivilege()方法将指定过程的执行权限分配给指定用户。

    通过调用$SYSTEM.SQL.Security.CheckPrivilege()方法,可以确定指定的用户是否具有指定过程的执行权限。

    要列出用户具有EXECUTE权限的所有过程,请转到管理门户。
    从系统管理中选择Security,然后选择Users或Roles。
    为所需的用户或角色选择Edit,然后选择SQL Procedures选项卡。
    从下拉列表中选择所需的名称空间。

    List 存储过程

    INFORMATION.SCHEMA.ROUTINES persistent类显示关于当前命名空间中所有例程和过程的信息。

    当在嵌入式SQL中指定时,INFORMATION.SCHEMA
    例程需要#include %occInclude宏预处理指令。
    动态SQL不需要这个指令。

    下面的例子返回例程名称、方法或查询名称、例程类型(过程或函数)、例程主体(SQL=class query with SQL, EXTERNAL=not a class query with SQL)、返回数据类型,以及当前命名空间中模式“Sample”中所有例程的例程定义:

    SELECT ROUTINE_NAME,METHOD_OR_QUERY_NAME,ROUTINE_TYPE,ROUTINE_BODY,SQL_DATA_ACCESS,IS_USER_DEFINED_CAST,
    DATA_TYPE||' '||CHARACTER_MAXIMUM_LENGTH AS Returns,NUMERIC_PRECISION||':'||NUMERIC_SCALE AS PrecisionScale,
    ROUTINE_DEFINITION 
    FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA='SQLUser'
    

    在这里插入图片描述

    INFORMATION.SCHEMA.PARAMETERS persistent类显示关于当前命名空间中所有例程和过程的输入和输出参数的信息。

    下面的示例返回例程名称、参数名称(不管是输入参数还是输出参数)以及当前命名空间中模式“Sample”中的所有例程的参数数据类型信息:

    SELECT SPECIFIC_NAME,PARAMETER_NAME,PARAMETER_MODE,ORDINAL_POSITION,
    DATA_TYPE,CHARACTER_MAXIMUM_LENGTH AS MaxLen,NUMERIC_PRECISION||':'||NUMERIC_SCALE AS PrecisionScale
    FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA='SQLUser'
    

    在这里插入图片描述

    使用管理门户SQL界面中的Catalog Details选项卡,可以为单个过程显示大部分相同的信息。
    过程的目录详细信息包括过程类型(查询或函数)、类名称、方法或查询名称、描述以及输入和输出参数的数量。
    目录详细信息存储过程信息显示还提供了运行存储过程的选项。

    展开全文
  • oracle 存储过程clob参数

    千次阅读 2020-12-23 15:32:26
    .Net处理Oracle中Clob类型字段总结最近在做项目中用到Clob这个字段,Clob是存储无限长字符的Oracle字段,用的时候网上找资料找了好久,内容不是很多,大部分都不能用,当然也有可以用的,测试了不同版本,整理了一下...
  • I'm trying to pass an array as a String in MySQL Stored Procedure but it doesn't work fine.Here's my SQL Codes:CREATE DEFINER=`root`@`localhost` PROCEDURE `search_equipment`(IN equip VARCHAR(100), IN ...
  • 1,调用没有参数存储过程set conn=server.CreateObject("adodb.connection")set cmd=server.CreateObject("adodb.command")strconn="dsn=pubs;uid=sa;pwd"conn.Open strconnset cmd.ActiveConnection=conncmd....
  • MySQL 存储过程返回多个值

    千次阅读 2021-01-26 05:13:08
    要开发返回多个值的存储过程,需要使用带有INOUT或OUT参数存储过程。返回多个值的存储过程示例我们看看orderinfo 表表中数据以下存储过程接受点买家姓名,并返回各个状态的订单总数。--手动创建存储过程 ...
  • 要开发返回多个值的存储过程,需要使用带有INOUT或OUT参数存储过程。咱们先来看一个orders表它的结构:然后嘞,咱们来看一个存储过程,它接受客户编号,并返回发货(shipped),取消(canceled),解决(resolved)和...
  • /*MySQL-进阶18存储过程 和 函数存储过程和...好处: 减少操作次数,减少了编译次数,减少了和服务器的连接次数,提高了效率*//*#一: 创建语句create procedure 存储过程名(参数列表)begin存储过程体(一组合法的SQL语法)...
  • 创建无参的存储过程这节我们主要来学习Mysql数据库的存储过程,我们知道我们要经常的对数据表进行增删改查的操作,或者叫CURD,实际上,当我们成功的输入SQL命令时,mysql引擎会对输入的命令进行语法分析,来检查...
  • oracle存储过程创建语法及常见异常:oracle存储过程语法:CREATE[ORReplace]PROCEDURE[schema.]procedure_name[(argument[{IN|OUT|INOUT}]datatype,...argument[{IN|OUT|INOUT}]datatype)]{IS|AS}[descriptionpart...
  • 常量:参与运算给变量赋值 字符串:用成对的单引号/双引号括起来 ...自定义局部变量:在封装的储存程序内部可用,调用结束后释放。 会话变量定义: set @var1 =值1; set @var1 =值1,@var2=值2; select 值1 int
  • 存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合,存储和和函数的区别在于函数必须有返回值,而存储过程没有,存储过程参数可以使用IN、OUT、INOUT类型,而函数的参数只能是IN类型。存储过程再...
  • 总体来说,sql sever和Mysql的存储...4. 再说参数,在MSSQL中我们一般会这么定义参数但是在mysql中这种格式是不可以的;首先在mysql中输入参数是in来表示,输出参数是out表示,如果不写,默认是in,其次在mysql中是...
  • Ø 存储过程的概念存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行。存储过程中可以包含逻辑控制语句和数据操纵语句,它可以...
  • DB2存储过程语法

    2021-03-07 18:39:05
    1. DB2存储过程示例:语法参数说明procedure-name: 存储过程的名字,在同一个数据库的同一模式下,不能存在存储过程名相同参数数目相同的存储过程,即使参数的类型不同也不行。(IN | OUT | INOUT parameter-name ...
  • 展开全部如何用JAVA调用存储过程CallableStatement 对象所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。62616964757a686964616fe59b9ee7ad9431333236383433已储存过程储存在数据库中。对已储存过程的调用...
  • Java中调用存储过程

    2021-02-28 09:25:08
    JDBC中的java.sql.CallableStatement对象所有的DBMS提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是CallableStatement对象所含的内容。这种调用是用一种换码语法来写...
  • 一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数,来执行它。在大型数据库中,存储过程和触发器具有重要的作用。无论是存储过程还是触发器,都是SQL语句和流程控制...
  • 存储过程是保存可以接受或返回用户提供参数的SQL语句集合。在日常的使用中,经常会遇到复杂的业务逻辑和对数据库的操作,使用存储过程可以进行封装。可以在数据库中定义子程序,然后把子程序存储在数据库服务器,...
  • 存储过程的概念存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行。存储过程中可以包含逻辑控制语句和数据操纵语句,它可以...
  • java执行存储过程

    2021-02-12 10:15:44
    结果参数是一种输出(OUT)参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN参数)、输出(OUT参数)或输入和输出(INOUT参数)的参数。问号将用作参数的占位符。 在JDBC中调用已储存过程的语法如下所...
  • 存储过程在t-sql中用到非常的多特别是安全性及大负载时都会到存储过程了,下面文章来各位介绍一篇非常详细的关于Sqlserver存储过程介绍。前言虽说现在orm,nosql对数据的操作会减少很多t-sql的编程,但是t-sql这...
  • MySQL存储过程及函数:创建存储过程:delimiter //create procedure 存储过程名称--begin--sql语句1--语句2.....--end//delimiter ;其中:参数为: [IN|OUT|INOUT] parameter_name type其中IN表示输入参数,OUT表示...
  • 从第一次使用jdbc去调用存储过程时,我就觉得传统的jdbc调用存储过程太“复杂”了,也可以说是繁琐了,复杂的不在于那些调用的代码,而是调用过程中代码里面往往都是由不确定参数个数(不确定输入参数个数、输出参数...
  • kettle 调用存储过程

    2021-05-05 01:30:27
    就是简单的更新两个表的字段,注意这里我定义了一个输出参数MESSAGE(用于捕获过程中的错误和提示过程运行情况)。我开始怀疑自己写的过程脚本是不是有不对的地方(虽然编译通过了),使用sqlerrm参数,输出过程错误,...
  • mysql 存储过程 print

    2021-01-18 23:23:41
    PHP调用MYSQL存储过程实例PHP调用MYSQL存储过程实例标签:mysql存储phpsqlquerycmd2010-09-26 11:1011552人阅读评论(3)收藏举报实例一:无参的...文章thinkyoung2016-01-20544浏览量存储过程实例存储过程:是为了...
  • mysql存储过程中的错误怎样跟踪关注:170答案:2mip版解决时间 2021-01-16 13:34提问者落叶、牵绊着思念2021-01-16 08:30mysql存储过程中的错误怎样跟踪最佳答案二级知识专家用命换你心2021-01-16 09:39DECLARE处理...
  • 调用 Oracle存储过程主要有两步:第一步,定义存储过程;第二步,调用存储过程。下面以一个具体的实例来学习如何使用FineReport调 用Oracle存储过程的。第一步,Oracel定义存储过程StScroe是 Oracele数据库中的张表...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 365,461
精华内容 146,184
关键字:

存储过程参数最大定义为多少