其实写逻辑的话并不难,主要是对新的语言和开发环境的陌生
不如看看下边的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 numberas
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函数查询效率太慢,有办法优化吗等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)