Informix存储过程题(谁能解决,小弟万分感谢)

Informix存储过程题(谁能解决,小弟万分感谢),第1张

其实写逻辑的话并不难,主要是对新的语言和开发环境的陌生

不如看看下边的informix存储过程的语法,学

写逻辑的话就是程序员的基本功了,掌握了语法,只要思路清晰,无论是什么语言什么环境都不会太难

======================================================================

存储过程基本语法:

1)创建存储过程

create procedure proc_name( [in_parameter_list])

returning out_para_list / out_result_set;

2)删除存储过程

drop procedure proc_name;

3)存储过程存放

存储过程信息放在sysprocedures系统目录表中,权限存放再sysprocauth表中。sysprocbody表存放每个存储过程的文本、编译伪代码、等信息。sysprocplan表存放查询执行计划和存储过程中引用的表格之间的相关性清单。

4)执行存储过程

。是标准SQL语言,通过数据库访问语言直接运行:

execute procedure proc_name(in_para_list)

returning out_para_list / out_result_set;

。在存储过程中调用;

call proc_name(in_para_list) returning out_para_list / out_result_set;

或 let local_variable = my_spl("argumeny_1);

调用不同数据库的存储过程: execute procedure database:my_sp1();

调用远程数据库不同网络节点:execute procedure database@sitename:my_sp1();

5、 其他常用语句

1)分支

if then

elif then

else

end if

2)循环(三种)

。for

for i=1 to 10

end for (没有分号)

。while

while

end while(没有分号)

。foreach

foreach select col1, into val1,

from tabname where

end foreach(没有分号)

3)循环控制语句:

。continue:条过余下的循环体,启动下一轮循环;

。EXIT:终止循环;

。RETURN:完成退出存储过程;

。RAISE EXCEPTION:退出,在循环外捕获错误;

例子:

foreach select col1, into val1,

from tabname where

if then

continue foreach;

end if;

for i=1 to 10

if then

exit for;

end if;

end for;

while

if then

return ;

end if;

end while;

end foreach(没有分号)

4)分块:BEGIN和END必须成对出现

BEGIN

on excewption

end exception

begin

end;

END;

四、SELECT语句

1、WHERE子句的关键字:

1)BETWEEN:指定数值范围;

2)IN:指定数值表;

3)LIKE:指定通配符文本查询;

4)MATCHES:指定通配符文本查询;

5)IS NULL:查询NULL值;

6)NOT:否定查询结果;

2、WHERE子句的 *** 作符

1)= ; 2)!= 不等于 3)<> 不等于 4)> 大于 5)>= 大于或等于;

6)<:小于; 7)<=:小于或等于;

eg1 : select from tablename

where col1 [not] between val1 and val2;

eg2 : select from tablename

where col1 [not] in [val1,val2,valn];

3、字符值搜索

1)子串:字符列名后用[],指定自串的开始和结束位置;如COL1[1,5];

注:选择不是从第一个字符开始的子串时,不能使用该列的索引;并且消耗资源多;

第一个数字代表开始位置;第二个数字代表终止位置,该数字不能大于列长度;

2)LIKE:

。%:代表0个或多个字符;

。下画线(_)代表一个字符;可以连续使用多个下画线代表多个字符;

。搜索原字符(%,_),需使用转意符(\);例如:

select from tablename where col1 like "%\%%":查询带%的内容;

注:。LIKE关键字是ANSI标准,方便移植;MATCHES功能有扩展;

。大小写有区别;

3)MATCHES:根据通配符搜索字符列。通配符与LIKE不同( 注:该命令大小写有区别)

。:代表0个或多个字符;

。?:代表一个字符;

。能对一个字符位指定字符范围和字符表,利用[]实现。(该功能LIKE没有);若要

指定字符范围,可以使用连字符(-)分开两个字符;例如:查询从A到L字母开始

的内容:

select from tablename where col1 matches "[A-L]";

。可以在前面加上插入符(^)否定一个范围的结果,例如:查询排除A到L字母开头

的内容:

select from tablename where col1 matches "[^A-L]";

。可以省略连字符,用[]指定字符表,将每个字符放在[]中,例如:查询以A、B、

C开头的信息;

select from tablename where col1 matches "[ABC]";

。前面加上插入符(^)可以否定查询结果,例如:上例取反:

select from tablename where col1 matches "[^ABC]";

。根据字母组合选择值:例如查询COL1中任何地方带‘ABC或abc’的信息:

select from tabname where col1 matches "[aA][bB][cC]"

说明:由于区分大小写,所以要对每一位指定大小写;

select from tabname where col1 matches "[A-Ls]"

查询COL1中以A-L和s开头的信息;

。若要使用元字符(和?),则需要使用转意符(\),例如:查询COL1中有的信

息:

select from tabname where col1 matches "\"

4、NULL 处理

1)列的值未知时,使用NULL值标识。

2)NULL值不同于0或空格,使用IS [NOT] NULL 查询未知值 或 NULL 值;

5、歧义列名

1)指定多个表中都存在的列名,需要加上表名限制,例如:

select col1,col2,col3 from t1,t2 where t1col1=t2col1 --错误,因COL1没限制

select acol1,acol2,bcol3 from t1 a,t2 b where acol1= bcol1;

5、外连接

1)返回主表的全部满足条件的记录(不管从表是否有匹配)和从表的匹配记录(相交记

录);

2)考虑点:

。一个表是主表,一个是从表;

。取得主表的所有记录,不管从表是否有匹配;

。从表名放在OUTER关键字后面;

。若从表没有符合连接条件的记录,则从表中的列未NULL值;

。若指定外连接,则连接条件放在WHERE子句中;

例子: select acol1,acol2 ,bcol3 from t1 a,outer t2 b

where acol1 = bcol1;

6、用括号嵌套简单连接(简单连接)

例子:select acol1,col2,bcol3,col4,col5 from t1 a,OUTER(t2 b,t3 c)

where acol1=bcol1

and bcol2=ccol2

and col5='abc'; (COL5在T3表中)

1)例子中首先将T3连接到T2,查询COL5=‘ABC’的内容;

2)然后将结果于表T1连接,取得最后结果;(是外连接)

3)OUTER关键字用于外连接T2和T3表的连接结果;

7、用括号嵌套外连接

例子:select acol1,col2,bcol3,col4,col5

from t1 a,OUTER(t2 b,OUTER t3 c)

where acol1=bcol1

and bcol2=ccol2

and col5='abc'; (COL5在T3表中)

注:T2与T3是外连接,T1与(T2和T3的外连接)结果是外连接;

8、GROUP BY 子句和HAVING 子句

1)例:select tabname[1,3],count() as cnt from systables group by tabname[1,3]

2)HAVING子句对一组采用过滤条件,通常与GROUP BY 子句一起使用,指定每个组的

过滤条件;

select tabname[1,3],count() as cnt

from systables group by tabname[1,3]

having count()>1

9、ORDER BY 子句

1)指定返回结果顺序;

2)该子句中列出一个或多个列;优先级依次降低;

3)ASC指定升序,DESC执行降序;

10、INTO TEMP 子句

1)生成临时表,在对话期间存在;

2)可以用DROP TABLE显示删除;

3)下列条件来临时表自动删除:1、退出程序时2、关闭当前数据库时3、切断当前数据库连接时。

五、日期时间 *** 作

1、数据类型:date , datetime;

2、当前日期时间:current;

3、当前日期:today;

4、相关函数:参见附件“常用函数”

5、例子:

1)当前日期时间: let cur_dtime_var = current; -- datetime

2)当前日期:let cur_date_var = today; --date

3)日期加减:

。 let tmp_date = today + 3 UNITS day -- 当前时间加三天

。let tmp_date = today + interval(7) day to day --当前时间加上7天

4)日期/时间转换成字符串:

define s char(20);

define y datetime year to second;

let y = current;

let s = year(y)||month(y)||day(y)

||hour(y)||extend(y,minute to minute)

|| extend(y,second to second);

5)字符串转换成日期/时间:

define dt datetime year to second;

let dt = EXTEND(DATETIME(2002-07-09 01:02:03) YEAR TO second, YEAR TO second);

六、游标 *** 作

1、定义

foreach cur_name for

select into from where

end foreach;

2、例子

define v1 integer;

define v2 datetime year to second;

define v3 varchar(10);

define v4 varchar(20);

FOREACH

select col1,col2,col3,col4 into v1,v2,v3,v4

from t1

RETURN v1,v2,v3,v4 WITH RESUME;

END FOREACH;

七、事务

1、语法:

begin work;

commit work / rollback work;

2、说明:

1)必须在日志数据库中,才能使用事务,否则提示错误;

2)事务中的 *** 作不能过多,否则可能造成长事务被取消或造成死锁;

八、异常处理方法

方法1:在每次 *** 作后进行判断。

缺点:该方法 *** 作烦琐,效率低下;

优点:能准确定位问题出处;

方法2:使用数据库提供的异常保护功能:

on exception

;

end exception;

缺点:不能准确定位问题的出处;

优点: *** 作简单、高效;

使用建议:根据实际情况选择,往往两者灵活结合使用效果最好;

九、存储过程跟踪方法

方法1、将跟踪内容写入表中,过程执行完成后查询;

方法2、在过程中直接返回跟踪对象的内容;

方法3、使用trace功能,详细使用参见后面的例子;

十、存储过程加载

方法一:使用dbaccess工具。使用NEW菜单项中直接输入或拷贝存储过程语句,再使用

RUN功能运行;

缺点:由于BUFFER大小有限,存储过程语句不能过多,超过部份自动截断;

方法二:使用dbaccess工具,使用choose功能直接选择编辑好的SQL文件,再使用RUN功能

运行。

方法三:使用工具dbaccess,直接加载SQL脚本:

dbaccess db_name file_namesql

十一、例子

1、用存储过程中返回一个或多个值

create procedure proc_test() returning int,datetime year to second,varchar(10);

define v1 integer;

define v2 datetime year to second;

define v3 varchar(10);

let v1 = 1;

let v2 = current;

let v3 = "test";

return v1,v2,v3;

end procedure;

2、用存储过程中返回一条记录

预设条件:表T1,字段col1 int, col2 datetime year to day,col3 char(10);

create procedure proc_test() returning int,datetime year to second,varchar(10);

define v1 integer;

define v2 datetime year to second;

define v3 varchar(10);

select col1,col2,col3 into v1,v2,v3

from t1

where col1=1; --col1为关键字,满足该条件的记录只有一条;

return v1,v2,v3;

end procedure;

3、用存储过程中返回多条记录(游标 -- cursor)

预设条件:表T1,字段col1 int, col2 datetime year to day,col3 char(10);

create procedure proc_test() returning int,datetime year to second,varchar(10);

define v1 integer;

define v2 datetime year to second;

define v3 varchar(10);

foreach

select col1,col2,col3 into v1,v2,v3

from t1;

return v1,v2,v3 with resume;

end foreach;

end procedure;

======================================================================

给你copy一段,自己看:

PL/SQL表---table()函数用法

/

PL/SQL表---table()函数用法:

利用table()函数,我们可以将PL/SQL返回的结果集代替table。

oracle内存表在查询和报表的时候用的比较多,它的速度相对物理表要快几十倍。

simple example:

1、table()结合数组:

/

create or replace type t_test as object(

id integer,

rq date,

mc varchar2(60)

);

create or replace type t_test_table as table of t_test;

create or replace function f_test_array(n in number default null) return t_test_table

as

v_test t_test_table := t_test_table();

begin

for i in 1 nvl(n,100) loop

v_testextend();

v_test(v_testcount) := t_test(i,sysdate,'mc'||i);

end loop;

return v_test;

end f_test_array;

/

select from table(f_test_array(10));

select from the(select f_test_array(10) from dual);

/

2、table()结合PIPELINED函数:

/

create or replace function f_test_pipe(n in number default null) return t_test_table PIPELINED

as

v_test t_test_table := t_test_table();

begin

for i in 1 nvl(n,100) loop

pipe row(t_test(i,sysdate,'mc'||i));

end loop;

return;

end f_test_pipe;

/

select from table(f_test_pipe(20));

select from the(select f_test_pipe(20) from dual);

/

3、table()结合系统包:

/

create table test (id varchar2(20));

insert into test values('1');

commit;

explain plan for select from test;

select from table(dbms_xplandisplay);

PL/SQL表---table()函数用法

/

PL/SQL表---table()函数用法:

利用table()函数,我们可以将PL/SQL返回的结果集代替table。

oracle内存表在查询和报表的时候用的比较多,它的速度相对物理表要快几十倍。

simple example:

1、table()结合数组:

/

create or replace type t_test as object(

id integer,

rq date,

mc varchar2(60)

);

create or replace type t_test_table as table of t_test;

create or replace function f_test_array(n in number default null) return t_test_table

as

v_test t_test_table := t_test_table();

begin

for i in 1 nvl(n,100) loop

v_testextend();

v_test(v_testcount) := t_test(i,sysdate,'mc'||i);

end loop;

return v_test;

end f_test_array;

/

select from table(f_test_array(10));

select from the(select f_test_array(10) from dual);

/

2、table()结合PIPELINED函数:

/

create or replace function f_test_pipe(n in number default null) return t_test_table PIPELINED

as

v_test t_test_table := t_test_table();

begin

for i in 1 nvl(n,100) loop

pipe row(t_test(i,sysdate,'mc'||i));

end loop;

return;

end f_test_pipe;

/

select from table(f_test_pipe(20));

select from the(select f_test_pipe(20) from dual);

/

3、table()结合系统包:

/

create table test (id varchar2(20));

insert into test values('1');

commit;

explain plan for select from test;

select from table(dbms_xplandisplay);

推荐方法:

create or replace function colinstr(p_string in varchar2, p_column in varchar2, p_seperator varchar2 default ':') return number

as

begin

    return instr(p_seperator||p_string||p_seperator, p_seperator||p_column||p_seperator);

end;

使用:select  from 表名 where colinstr(‘Hello:Welcome:Good’,表字段)>0;

假设要查找某个表字段的值是冒号分割列表里的单词就可以这么找。摆脱完美的拖延纠结症,就这样效率就上去了。

你可以把文字和路径用一个特定的符号连接成一个字符串,再把这个字符串存到数据库字段中,比如用竖线符号:

var str = 文字+"|"+路径;

取出数据时再把它分割为两个数据:

var arr = 数据库返回的数据split("|");

这时候 arr[0] 是文字,arr[1]是路径

详细步骤,已测试成功[@more@]

1、备份数据库,包括 master 和你要分离数据与日志的应用库,最好是备份所有数据库;

2、检查数据库的日志是否有单独的存放设备,如有,则直接到第5步;

3、如没有单独的日志设备,则增加一个设备:disk init ;

4、alter database db_name log on new_log_device=xxx

5、sp_logdevice dbname,new_logdev (移动日志设备)

6、sp_dropsegment logsegment, db_name, device_name (如果数据库有多个设备既放数据又放日志,则

要相应的运行几次

7、创建一个临时表,然后往里面插入足够的数据,然后截断日志

use db_name

go

create table t1 (id int)

go

declare @loop int

select @loop = 1

while(@loop<500)

begin

insert t1 values(@loop)

select @loop = @loop + 1

end

go

dump tran db_name with truncate_only

go

8、到此,数据与日志的分离已经完成,使用sp_helpdb db_name或sp_helplog查看是否已分离。

增加和删除 segment 并不移动当前的已分配空间。日志至少有一个扩充(extend)位于以前的 segment

上(还记得吗,为对象分配存贮单元时,实际是以 extend 为单位的。)。如果当前 extend 被填满,需要再

为日志分配时,ASE会在新的 segment 上分配(segment 约束它不得不这么做)。此时,截断日志就可以回收

以前分配的 extend 了。

最后,还是要备份所有数据库

以上就是关于Informix存储过程题(谁能解决,小弟万分感谢)全部的内容,包括:Informix存储过程题(谁能解决,小弟万分感谢)、oracle 数据库 sql语言 数组和表join的方法、oracle数据库中STR2NUMLIST函数查询效率太慢,有办法优化吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/9304582.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存