您的位置:首页 > 数据库

informix数据库基础

2006-09-26 19:20 225 查看
公司正在做的项目使用了informix作为数据库,用下来,感觉比SQL Server难用多了,也没有完整的帮助文档。在网上搜索了N多帖子,才汇聚成下面的文章,谢谢http://bbs.chinaunix.net/的朋友们的共享。

另外informix官方资料可以去http://www.informix.com.ua/doc/9.40/查找,比较全,而且全是E文的。

1.informix for linux安装

第一步:下载
        ids 9.4 for linux:
        ftp://ftp.youngcow.net/Special/Database/DatabaseServer/Informix/InformixDynamicServerVersion9.4/IIUG-IDS-9.4-linux.zip         这个线程有限制
        http://202.96.110.133/informix/ids9.4/IIUG-IDS-9.4-linux.zip         这个更快,视网络定吧;

        csdk for linux:
        ftp://ftp.software.ibm.com/software/data/informix/downloads/clientsdk.2.81.UC2.LINUX.tar
第二步:linux搭建安装informix的环境

        建立informix组:groupadd -g 20000 informix

        建立informix用户:useradd -u 20000 -g 20000 -d /home/informix -m informix

        修改informix用户环境变量:
        修改 .bash_profile文件 增加以下环境变量

        INFORMIXDIR=/home/informix
        INFORMIXSERVER=cs_dbs
        ONCONFIG=onconfig.cs
        DBDATE=MDY4*
        LD_LIBRARY_PATH=$INFORMIXDIR/lib/INFORMIXDIR/lib/esql/LD_LIBRARY_PATH
        export INFORMIXDIR INFORMIXSERVER ONCONFIG LD_LIBRARY_PATH
        PATH=$PATH/INFORMIXDIR/bin
        export PATH
        这个就不用偶解释了吧;

第三步:准备安装文件

        zip文件解压就不用偶说了吧;呵呵

        把解开的一个Linux-IDS.9.40.tc1e1.cpio与clientsdk.2.81.UC2.LINUX.tar文件传入环境中;

        解开Linux-IDS.9.40.tc1e1.cpio:cpio -idmv <Linux-IDS.9.40.tc1e1.cpio;
        生成的文件你看的到;

        解开clientsdk.2.81.UC2.LINUX.tar:tar xvf clientsdk.2.81.UC2.LINUX.tar;
        生成csdk.cpi;

        解开csdk.cpi cpio -idmv <csdk.cpi;
        生成的文件你看的到;

第四步:开始安装

        首先用informix用户登陆

        安装ids:在informix目录下运行./installserver

        碰到提示,直接回车;

        完成后su到root运行RUN_AS_ROOT.server;

        这样你的ids就安装好了;

        安装csdk:在inforomix目录下运行./installclientsdk;

        碰到提示敲yes,回车;

        完成后su到root运行RUN_AS_ROOT.clientsdk;

        这样你的clientsdk就装好了;

第五步:开始配置

        1、配置/etc/services文件
        sqlexe    1526/tcp
           sqlexec          1528/tcp
       
        --sqlexe和sqlexec是services 名字,1526、1528是端口号;
        --TCP/IP表示TCP/IP协议

        2、配置/etc/hosts文件
        192.168.28.1        linux(本主机名称)

        3、配置$INFORMIXDIR/etc/sqlhosts文件
        cs_dbs                onipcshm        linux        sqlexe
        cs_dbs_tcp        onsoctcp        linux        sqlexec

        --这里配置了共享内存方式和soctcp方式连接数据库的两种方式;linux代表主机名;sqlexe/sqlexec分别代表在services文件中配的服务;
        --另外需要注意的是,informix for linux 9.4版中release提到不支持tlitcp方式;所以这里采用的onsoctcp方式;
        --若sqlhosts文件配置了tlitcp方式或者说sqlhosts文件中的配置和onconfig.cs文件配置不一样,会出现很多人都经常碰到的25507错误;

        4、建立空间
        以informix用户操作
        在INFORMIXDIR中建立dbs目录;(便于区分拉)
        首先touch rootdbs logdbs phydbs blobdbs tmpdbs datadbs
        然后chmod 660 *
        保证所有的dbs文件都是informix用户informix组;权限都是660;       

        5、配置$INFORMIXDIR/etc/onconfig.cs文件
        以下列出需要注意的几点内容:

        --rootdbs路径、空间
        ROOTNAME        rootdbs         # Root dbspace name
        ROOTPATH        /home/informix/dbs/rootdbs  # Path for device containing root dbspace
        ROOTOFFSET      0               # Offset of root dbspace into device (Kbytes)
        ROOTSIZE        100000          # Size of root dbspace (Kbytes)

        --物理日志的dbs空间,先用rootdbs的20M;
        PHYSDBS         rootdbs         # Location (dbspace) of physical log
        PHYSFILE        20000           # Physical log file size (Kbytes)

        --逻辑日志用默认的
        # Logical Log Configuration

        LOGFILES        6               # Number of logical log files
        LOGSIZE         2000            # Logical log size (Kbytes)

        --把磁带的东西都改成/dev/null       
        TAPEDEV         /dev/null       # Tape device path
        TAPEBLK         32              # Tape block size (Kbytes)
        TAPESIZE        10240           # Maximum amount of data to put on tape (Kbytes)

        # Log Archive Tape Device

        LTAPEDEV        /dev/null       # Log tape device path
        LTAPEBLK        32              # Log tape block size (Kbytes)
        LTAPESIZE       10240           # Max amount of data to put on log tape (Kbytes)

        --配置数据库服务器参数,根据自己机器配置的实际情况分配locks和buffers;
        SERVERNUM       0               # Unique id corresponding to a OnLine instance
        DBSERVERNAME    cs_dbs          # Name of default database server
        DBSERVERALIASES cs_dbs_tcp      # List of alternate dbservernames
        NETTYPE         ipcshm,1,8,CPU  # Configure poll thread(s) for nettype
        NETTYPE         soctcp,1,8,NET  # Configure poll thread(s) for nettype

        LOCKS                5000                # Maximum number of locks
        BUFFERS                500                # Maximum number of shared buffers
        NUMAIOVPS        2                # Number of IO vps
        PHYSBUFF        32                # Physical log buffer size
4000
(Kbytes)
        LOGBUFF                32                # Logical log buffer size (Kbytes)
        CLEANERS        1                # Number of buffer cleaner processes
        SHMBASE                0x10000000        # Shared memory base address
        SHMVIRTSIZE     8000                # initial virtual shared memory segment size
        SHMADD                8192                # Size of new shared memory segments (Kbytes)

        另外就是onconfig.cs文件中所有/usr/informix都替换成/home/informix/

        6、初始化数据库了
        oninit -ivy
        成功后用onstat -i 就可以看到了
        Informix Dynamic Server Version 9.40.UC1E1   -- On-Line -- Up 00:31:47 -- 18872
        Kbytes
        onstat>;
       
        7、完善数据库空间
       
        下面提供一个我经常使用的shell

        echo "Add blobdbs, tmpdbs0, phydbs, logdbs..."
        echo "====================================================="

        onspaces -c -b blobdbs -g 32 -p /home/informix/dbs/blobdbs -o 0 -s  48000
        onspaces -c -d tmpdbs -t -p /home/informix/dbs/tmpdbs -o 0 -s 100000

        onspaces -c -d phydbs -p /home/informix/dbs/phydbs -o 0 -s 50200
        onspaces -c -d logdbs -p /home/informix/dbs/logdbs -o 0 -s 200000

        echo "/nShut Down Server to Quiescent Mode..."
        echo "====================================================="
        onmode -s -y
        sleep 5

        echo "Adding Logical Log/n"
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 20000
        onparams -a -d logdbs -s 10000

        echo "/nArchiving Database Server Please Wait 20 seconds./n"
        echo "====================================================="
        ontape -s
        sleep 5

        onmode -l
        onmode -l
        onmode -l
        onmode -l
        onmode -l
        onmode -l
        onmode -c
        sleep 10

        echo "/nDrop the old Logical Log Files... /n"
        echo "====================================================="
        onparams -d -l 1 -y
        onparams -d -l 2 -y
        onparams -d -l 3 -y
        onparams -d -l 4 -y
        onparams -d -l 5 -y
        onparams -d -l 6 -y

        echo "/nChange Physical Log Files, please wait about 1 minutes.../n"
        echo "====================================================="
        onparams -p -s 50000 -d phydbs -y
        sleep 100

        echo "/nNow add more dbspaces/chunks.../n"
        echo "====================================================="

        onspaces -c -d datadbs   -p /home/informix/dbs/datadbs -o 0 -s 500000

        echo "/nTake a level 0 archive./n"
        echo "====================================================="

        ontape -s  -L 0

        echo "/nReboot IDS.../n/n"
        echo "====================================================="

        onmode -ky
        oninit

        sleep 10

        echo "/n====================================================="
        echo "Well done! /n"
        echo "====================================================="

        最后修改onconfig.cs文件
        DBSPACETEMP     tmpdbs         # Default temp dbspaces
        onmode -ky
        oninit

2.informix SQL汇总

CREATE DATABASE database_name [WITH LOG IN “pathname”]

创建数据库。

database_name:数据库名称。

“pathname”:事务处理日志文件。

创建一database_name.dbs目录,存取权限由GRANT设定,无日志文件就不能使用

BEGIN WORK等事务语句(可用START DATABASE语句来改变)。

可选定当前数据库的日志文件。

如:select dirpath form systables where tabtype = “L”;

例:create databse customerdb with log in “/usr/john/log/customer.log”;

DATABASE databse-name [EXCLUSIVE]

选择数据库。

database_name:数据库名称。

EXCLUSIVE:独占状态。

存取当前目录和DBPATH中指定的目录下的数据库,事务中处理过程中不要使用此语句。

例:dtabase customerdb;

CLOSE DATABASE

关闭当前数据库。

database_name:数据库名称。

此语句之后,只有下列语句合法:

CREATE DATABASE; DATABASE; DROP DATABSE; ROLLFORWARD DATABASE;

删除数据库前必须使用此语句。

例:close database;

DROP DATABASE database_name

删除指定数据库。

database_name:数据库名称。 用户是DBA或所有表的拥有者;删除所有文件,但不包括数据库目录;不允许删除当前数据库(须先关闭当前数据库);事务中处理过程中不能使用此语句,通过ROLLBACK WORK 也不可将数据库恢复。

例:drop databse customerdb;

CREATE [TEMP] TABLE table-name (column_name datatype [NOT NULL], …)

[IN “pathname”]

创建表或临时表。

table-name :表名称。

column_name:字段名称。

data-type:字段数据类型。

path-name:指定表的存放位置

TEMP用于指定建立临时表;表名要唯一,字段要唯一;有CONNECT权限的用户可建立临时表;创建的表缺省允许CONNECT用户存取,但不可以ALTER。

例:create table user

( c0 serial not null, c1 char (10),

c2 char(2),

c3 smallint,

c4 decimal(6,3),

c5 date

) in “usr/john/customer.dbs/user;

ALTER TABLE

ALTER TABLE table-name

{ADD (newcol_name newcol_type [BEFORE oldcol_name], …) | DROP (oldcol_name, …)

| MODIFY (oldcol_name newcol_type [NOT NULL], … )}, …

修改表结构。

table-name:表名称。

newcol_name:新字段名称

newcol_type:新字段类型

oldcol_name:老字段名称

可以使用单个或多个ADD子句、DROP子句、MODIFY子句,但某个字句失败,操作即中止;原字段是NULL,不允许MODIFY为NOT NULL,除非所有NULL字段中均非空,反之可以;ALTER使用者是表的拥有者或拥有DBA权限,或被授权;事务中处理过程中不要使用此语句。

例:alter table user

add ( c6 char(20) before c5);

RENAME TABLE oldname TO newname

修改表名。

oldname:原名称。

newname:新名称。

RENAME使用者是表的拥有者或拥有DBA权限,或被授权;事务中处理过程中不要使用此语句。 例:rename user to bbb;

DROP TABLE table-name

删除表。

table-name:表名称。

删除表意味着删除其中所有数据、各字段上的索引及对表的赋权、视图等;用户不能删除任何系统目录表;语句使用者是表拥有者或拥有DBA权限,事务中处理过程中不要使用此语句。

RENAME COLUMN table.oldcolumn, TO newcolumn

修改字段名。

table.oldcolumn:表名及原字段名称

newcolumn:新字段名称。

语句使用者是表的拥有者或拥有DBA权限或有ALTER权限的用户,事务中处理过程中不要使用此语句。

例:rename column user.c6 to c7;

CREATE VIEW view-name column-list

CREATE VIEW view-name column-list AS select_statement [WITH CHECK OPTION]

创建视图。

view-name:视图名称。

column-list:字段列表。

select_statement:SELECT语句。

以下语句不使用视图:ALTER TABLE,DROP INDEX,ALTER INDEX,LOCK TABLE,CREATE INDEX, RENAME TABLE;视图将延用基表的字段名,对表达式等虚字段和多表间字段重名必须指明标识其字段名;若对视图中某些字段命名,则所有字段都必须命名;视图中数据类型延用基表中的数据类型,虚字段起诀于表达式;不能使用ORDER BY和UNION子句;对视图中所有的字段要有SELECT权限;事务中处理过程中使用此语句,即使事务回滚,视图也将建立,不能恢复。

例:create view v_user as select * from user where c1 = “B1”;

DROP VIEW view-name

删除视图。

view-name:视图名称。

用户可删除自己建立的视图;视图的后代视图也被删除;事务中处理中不要使用此语句。

例:drop view v_user;

CREATE INDEX

CREATE [UNIQUE/DISTINCT] [CLUSTER] INDEX index_name ON table_name

([column_name ASC/DESC],…)

创建索引。

index_name:索引名称。

table_name:表名称。

column_name:字段名称。

UNIQUE/DISTINCT:唯一索引。

CLUSTER:使表的物理存放顺序按索引排列。

ASC/DESC:升序或降序,缺省升序。

语句执行时,将表的状态置为EXCLUSIVE;复合索引最多包含8个字段,所有字段长度和不得大于120字节;事务中处理过程中使用此语句,即使事务回滚,索引将建立,不能恢复。

例:create cluster index ix_user on user(c5);

ALTER INDEX index-name TO [NOT] CLUSTER

修改索引性质。

index-name:索引名称。

TO [NOT] CLUSTER:去掉或加上CLUSTER属性。

语句执行时,将表的状态置为EXCLUSIVE;事务中处理过程中使用此语句,即使事务回滚,索引性质将改变,不能恢复。

例:alter index ix_user to not cluster;

DROP INDEX index-name

删除索引。

index-name:索引名称。

语句使用者是索引的拥有者或拥有DBA权限,事务中处理过程中不要使用此语句,否则事务无法恢复。

例:drop index ix_user;

CREATE SYNONYM synonym FOR table-name

创建同义名。

synonym:同义名

table-name:表名称

数据库的创建者可以使用同义名;没有赋予同义名权限的用户不能使用同义名;同义名不能和表名相同;事务中处理过程中不要使用此语句。

例:create synonym user_alias for user;

DROP SYNONYM synonym

删除同义名。

synonym:同义名

可以删除自己建立的同义名;事务中处理过程中不要使用此语句,否则无法恢复。

例:drop synonym user_alias;

UPDATE STATISTICS [FOR TABLE table-name]

更新数据库的统计数字。

table-name:表名称

此语句仅作用于当前数据库;可提高查询效率;只有执行此语句,才改变统计数据。

例:update statistics for table user;

GRANT {DBA|RESOURCE|CONNECT} TO {PUBLIC|user-list}
授权命令。

PUBLIC|user-list:全部或指定的用户。

三种权限居且仅居其一,事务处理过程中不要执行GRANT语句。

例:grant resource to pulbic;

GRANT tab-privilege ON table-name TO {PUBLIC|user-list} [WITH GRANT OPTION]

授表级权限。

tab-privilege:表级权限。

table-name:表名称。

PUBLIC|user-list:全部或指定的用户。

[WITH GRANT OPTION]:表示被授权用户有否权限进行二次授权。

用户可以在自己建立表达式或被[WITH GRANT OPTION]准许的表中进行赋权;限定越多的权限优先级越高。

例:grant update(c1,c6) on user to dick with grant option;

附(INFORMIX的权限)

(1) 数据库的权限(控制对数据库的访问以及数据库中表的创建和删除)

DBA权限:全部权利,修改系统表,建立和删除表与索引、增加和恢复表数据,以及授予其他用户数据库权限等;

RESOURCE权限:允许对数据库表中的数据进行存取,建立永久性表以及索引。

CONNECT权限:只允许对数据库表中的数据进行存取,建立和删除视图与临时表。

(2)表级权限(对表的建立、修改、检索和更新等权限)

ALTER:更改权限

DELETE:删除权限

INDEX:索引权限

INSERT:插入权限

SELECT [(cols)]:指定字段或所有字段上的查询权限,不指明字段缺省为所有字段。

UPDATE [(cols)] :指定字段或所有字段上的更新权限,不指明字段缺省为所有字段。

ALL [PRIVILEGES]:以上所有表级权限

REVOKE {DBA|RESOURCE|CONNECT} FROM {PUBLIC|user-list}

收权命令。

PUBLIC|user-list:全部或指定的用户。

三种权限居且仅居其一,事务处理过程中不要执行GRANT语句。

例:revoke resource from john;

REVOKE tab-privilege ON table-name FROM {PUBLIC|user-list}

收表级权限。

tab-privilege:表级权限。

table-name:表名称。

PUBLIC|user-list:全部或指定的用户。

[WITH GRANT OPTION]:表示被授权用户有否权限进行二次授权。

用户只能取消由其本人赋予其他用户的表级存取权限;不能取消自己的权限,对SELECT和UPDATE作取消时,将取消所有表中字段的SELECT 和UPDATE权限。

例;revoke update on user from dick;

LOCK TABLE table-name IN {SHARE|EXCLUSIVE} MODE

记录级加锁和表级加锁或文件加锁。

table-name:表名称。

SHARE:允许读表中数据,但不允许作任何修改

EXCLUSIVE:禁止其他任何形式访问表

每次只能对表琐定一次;事务处理过程中,BEGIN WORK后立即执行LOCK TABLE以取代记录级加锁,COMMIT WORK和ROLLBACK WORK语句取消所有对表的加锁;若没有事务处理,锁将保持到用户退出或执行UNLOCK为止。

例:lock table user in exclusive mode;

UNLOCK TABLE table-name

取消记录级加锁和表级加锁或文件加锁。

table-name:表名称。

例:unlock user;

SET LOCK MODE TO [NOT] WAIT
改变锁定状态。

TO [NOT]:等待解锁,有可能被死锁或不等待并提示错误信息,表示此记录被锁,缺省值。

访问一个EXCLUSIVE状态下的记录,将返回一个错误。

START DATABSE db_name [WITH LOG IN “pathname”]

启动事务处理。

“pathname”:事务处理日志文件。

执行该语句前,需要先关闭当前数据库。

例;clost database;

start databse customer with log in “/usr/john/log/customer.log”;

BEGIN WORK

开始事务。例:begin work;

COMMIT WORK

提交(正常结束)事务。例:commit work;

ROLLBACK WORK

回滚(非正常结束)事务。例:rollback work;

SELECT

SELECT select_list FROM tab_name|view_name

WHERE condition

GROUP BY column_name

HAVING condition

ORDER BY column_list

INTO TEMP table_name

查询语句。

select_list:选择表或*

tab_name:表名称

view_name:视图名称。

condition:查询条件,可使用BETWEEN、IN、LIKE、IS NULL、LIKE、MATCHES、NOT、

AND、OR、=、!=或<>;、>;、 >;= 、<=、<、ALL、ANY、SOME

column_name:分组字段名称

condition:群聚条件

column_list:排序字段列表,缺省ASC,可指定DSC;排序时,NULL值小于非零值。

table_name:临时表名称

例:略

附(常用函数)

(1)集合函数:

count(*)、

sum(数据项/表达式)、avg(数据项/表达式)、max(数据项/表达式)、min(数据项/表达式)

count(distinct 数据项/表达式)、sum(distinct数据项/表达式)、avg(distinct数据项/表达式)

(2)代数函数和三角函数

HEX(数据项/表达式)、ROUND(数据项/表达式)、TRUNC(数据项/表达式)、

TAN(数据项/表达式)、ABS(数据项/表达式)、MOD(被除数,除数)

(3)统计函数

标准差,stdev()、方差,variance()、范围,rang()

(4)时间函数

DAY(日期/时间表达式):返回数字型

MONTH(日期/时间表达式):返回整数

WEEKDAY(日期/时间表达式):0��6,0星期天,1星期一;返回整数

YEAR(日期/时间表达式)、返回整数

DATE(非日期表达式):返回日期型

EXTEND(日期/时间表达式,[第一个至最后一个]):返回指定的整数

MDY(月,日,年):返回日期型

CURRENT:返回日期型

(5)时间函数

ROUND(),四舍五入。如:ROUND(10.95,position)position进行四舍五入的前一位置

TRUNC(),截取。如:TRUNC(10.95,0)position截取的位置

INFORMIX临时表在下列情况下自动取消:

A.退出数据库访问工具(如DBACCESS)

B.SQL通话结束(DISCONNECT)

C.发出取消表语句

D.退出程序时

INSERT
INSERT INTO view_name|table_name [(column_list)] VALUES (value_list)

或 INSERT INTO view_name|table_name [(column_list)] select_statement

插入数据

view_name|table_name:视图名或表名称

column_list:数据项列表。

value_list:值列表

select_statement:查询语句。

例:略

DELETE FROM view_name|table_name WHERE search-conditions
删除语句。

view_name|table_name:视图名或表名称

search-conditions;删除条件

例:略

UPDATE
UPDATE view_name|table_name SET column_1 = value_1ist WHERE search_conditions

或UPDATE view_name|table_name SET column_1|* = value_1ist WHERE search_conditions

更新数据语句。

view_name|table_name:表名称或视图表名称

value_1ist:字段值

search_conditions:更新数据的条件

例:略

CHECK TABLE table-name
检查索引语句。

语句使用者是表的拥有者或拥有DBA权限;不能对systable使用此语句。

例:略

REPAIR TABLE table-name
修复索引。

语句使用者是表的拥有者或拥有DBA权限;不能对systable使用此语句。

例:略

LOAD FROM “file-name” INSERT INTO table_name [(column_name[,…])]
将文本数据栽入表中。

例:load form “aa.txt” insert into user;

UNLOAD TO “pathname”
将表中数据卸为文本。

例:unload to “aa.txt” select * from user;

INFO
系统信息查询。

INFO TABLES:得到当前数据库上表的名字。

INFO columns FOR table_name:指定表上的字段信息。

INFO INDEXES FOR table_name:指定表上的索引信息。

INFO [ACCESS|PRIVILEGES] FOR table_name:指定表上的存取权限。

INFO STATUS FOR table_name:指定表的状态信息。

例: info tables;

1.select 语句中使用sort,或join

如果你有排序和连接操作,你可以先select数据到一个临时表中,然后再对临时表进行处理。因为临时表是建立在内存中,所以比建立在磁盘上表操作要快的多。

如:

SELECT time_records.*, case_name

FROM time_records, OUTER cases

WHERE time_records.client = "AA1000"

AND time_records.case_no = cases.case_no

ORDER BY time_records.case_no

这个语句返回34个经过排序的记录,花费了5分钟42秒。而:

SELECT time_records.*, case_name

FROM time_records, OUTER cases

WHERE time_records.client = "AA1000"

AND time_records.case_no = cases.case_no

INTO temp foo;

SELECT * from foo ORDER BY case_no

返回34条记录,只花费了59秒。

2.使用not in 或者not exists 语句

下面的语句看上去没有任何问题,但是可能执行的非常慢:

SELECT code FROM table1

WHERE code NOT IN ( SELECT code FROM table2 )

如果使用下面的方法:

SELECT code, 0 flag

FROM table1

INTO TEMP tflag;

然后:

UPDATE tflag SET flag = 1

WHERE code IN ( SELECT code

FROM table2

WHERE tflag.code = table2.code );

然后:

SELECT * FROM

tflag

WHERE flag = 0;

看上去也许要花费更长的时间,但是你会发现不是这样。

事实上这种方式效率更快。有可能第一种方法也会很快,那是在对相关的每个字段都建立了索引的情况下,但是那显然不是一个好的注意。

3.避免使用过多的“or"

如果有可能的话,尽量避免过多地使用or:

WHERE a = "B" OR a = "C"

要比

WHERE a IN ("B","C"


慢。

有时甚至UNION会比OR要快。

4.使用索引。

在所有的join和order by 的字段上建立索引。
在where中的大多数字段建立索引。
WHERE datecol >;= "this/date" AND datecol <= "that/date"
要比
WHERE datecol BETWEEN "this/date" AND "that/date" 慢

如何在shell脚本中使用一个sql查询的结果?

以下的是一个运行在sh/ksh下面的脚本。在online中,如果你想要更新一个有许多表的数据库的统计信息。这个脚本不太好。因为这个脚本只能单个处理数据库中的表,而不能同时处理大量的表。

例子:

# update_em

# Run UPDATE STATISTICS on a table by table basis

#

DATABASE=$1

if [ -z "$DATABASE" ]

then

echo "usage: update_em dbname" >;&2

exit 1

fi

isql $DATABASE - < dev/null | isql $DATABASE -

output to pipe "cat" without headings

select "update statistics for table ", tabname, ";"

from systables where tabid >;= 100 order by tabname;

EOF

exit 0

也许你已经注意到exit的返回值对不同的isql不是都相同,因此这样作不是很可靠,代替通过$?来检查返回值的更好的主意是将标准错误重定向到一个文件中,然后在这个文件中grep “error"。例如:

# Generate the data

isql -qr <<!>;stage.rep 2>;$stage.err

database $database;

select ...

!

# Check for errors

if grep -i "error" $stage.err >;/dev/null

then

...error_handler...

fi

为什么不能对一个计算产生的字段创建视图?

问题:为什么我不能创建视图:

CREATE VIEW tst AS

SELECT ship_charge - totval cout

FROM orders WHERE ship_charge >; 0;

回答:你应该这样写:

CREATE VIEW tst (cout) AS

SELECT ship_charge - totval

FROM orders WHERE ship_charge >; 0;

如何只select 出数据库中的部分数据(例如10%)。

问题:如果你想要得到一个select 语句正常返回的数据的一部分,例如:

SELECT firstname, lastname, city, state

FROM bigdatabase

WHERE state = "TX"

回答:

有一个方法可以返回一个近似值,只需要在where后加上:

AND rowid=(trunc(rowid/x)*x)

其中的x代表你想要返回的总的记录的1/x。需要说明的是,这种方法只能返回一个近似的值,并且表中的数据在物理上分布的连续性。

如何创建一个表结构和永久表完全一致的临时表。 例如:CREATE TEMP TABLE mytemp (prodno LIKE product.prodno

desc LIKE product.desc)

你可以使用如下的语句:

SELECT prodno, desc FROM product

WHERE ROWID = -1

INSERT INTO TEMP mytemp

如何更改serial类型下一次插入操作产生的值?

我们知道serial类型的字段是系统自动增加的整数字段,那么怎样能控制下一个serial类型字段的值。

想要下一个插入的serial类型的值比默认值大,可以用:

ALTER TABLE tabname MODIFY( ser_col_name SERIAL([new_start_number])

想要下一个插入的serial类型的值比默认的值要小,首先需要将serial类型重新置为1:

INSERT INTO table (serial_column) VALUES (2147483647);

INSERT INTO table (serial_column) VALUES (0); -- 重新从1开始!

....然后执行ALTER TABLE(就像上面的做法一样)。

如何在发生错误的时候终止sql脚本的执行?

如果你创建了一个sql脚本,并且在UNIX命令行中使用以下的方式来执行这个脚本:

$ dbaccess <database>; <脚本文件名>;

这时,脚本中的所有的sql语句都会被执行,即使其中的一个sql语句发生了错误。例如,如果你脚本中为如下的语句:

BEGIN WORK;

INSERT INTO history

SELECT *

FROM current

WHERE month = 11;

DELETE FROM current

WHERE month = 11;

COMMIT WORK;

如果INSERT语句失败了,DELETE语句仍旧会继续执行。直到commit work。这样的后果可能会很严重。你可以通过设置一个环境变量来防止这种情况的发生。

DBACCNOIGN=1

如何设置decimal字段运算结果的精度?

假定你使用dbaccess或者isql,设置环境变量DBFLTMASK=6 就可以设置为小数点后面6位,比如:

CREATE TEMP TABLE t

( col_a DECIMAL(8,4) NOT NULL,

col_b DECIMAL(8,4) NOT NULL,

col_c DECIMAL(8,4) NOT NULL

);

INSERT INTO t VALUES(1.2345, 3.4567, 5.6789);

SELECT (col_a + col_b) / col_c AS value FROM t;

value 0.826075

如果DBFLTMASK=7

value 0.8260755

为什么我们有时会遇到sysprocplan表被锁的提示?

sysprocplan表是sysmaster库中的一个表,其中记录存储过程经过优化的查询计划。每当查询树中的数据库对象有任何结构上的变化,这个查询计划就会自动更新。如果对查询树中存在的任何表有update statistics操作,也会自动更新查询计划。在查询计划更新的时候,会对sysporcplan表中的相关记录加锁。

注意:每次你对一个表更新统计的时候,也同时会更新于这个表相关的存储过程,即UPDATE STATISTICS FOR PROCEDURE 。

你可以作的另外一件事情就是:在存储过程中使用SET OPTIMIZATION LOW,这会让优化器在存储过程运行的时候不会试图去重新优化它。否则存储过程通常都会被重新优化一次。

如何删除掉表中重复的记录?

假设“keycol”字段的值唯一,而且没有对表进行分片,并且没有其它的人正在删除"sometable"中的记录,你可以执行如下的SQL:

delete from sometable as a

where rowid <>; (select min(rowid) from sometable where keycol = a.keycol)

如果这个表使用表分片,rowid不存在,你还可以用如下的方法:

BEGIN WORK;

SELECT DISTINCT * FROM Table INTO TEMP Temp1;

DELETE FROM Table WHERE 1 = 1;

INSERT INTO Table SELECT * FROM Temp1;

COMMIT WORK;

对于规模较小或中等的表,并且你有足够的存储空间来存储整个的临时表的时候,这种方法通常十分有效。

如何加快SELECT COUNT(DISTINCT)的速度。

通常“SELECT COUNT(DISTINCT)”这样的操作要花费比较长的时间,如果你这样作:

SELECT UNIQUE xxx INTO TEMP XXX " 然后再"SELECT COUNT(*) FROM TEMP XXX"

NULL值的使用

RDSQL中字段缺省值为空;并且对数值型的0和空值,以及字符型的空白和空值区别对待。
数值表达式中某个变为空,则整个表达式值为空;
聚合函数中,对空值忽略不计,若全部为空值,除COUNT(*)返回0外,其余返回空值。
布尔表达式中,结果可能为“未知”(见下表)。如TRUE AND NULL 结果为 “未知”,对“未知”结果在RDSQL中看作不符合查询条件。

结合上表,分析下列子句 ,其中n1=20;n2为空;n3=30。结果如右。

where n1*n2 < 1000 and n3 = 30; 结果:不符合查询条件
where n1*n2 < 1000 or n3 = 30; 结果:符合查询条件

ORDER BY子句中的空值,每一个空值为一组。
INSERT或UPDATE时,可使用关键字NULL/null表示空值。
字段是否可以为空,由CREATE TABLE语句中是否有NOT NULL指定或由ALTER修改。

Q:select count(*) from t1和select count(c1) from t1是否一样?

字符查找,主要使用LIKE和MATCHES。

LIKE
MATCHES
意义

%
*
匹配0或多个字符

-
?
匹配一个字符

/
/
转义字符


[]
选择匹配

例:matches ‘*Sp’;匹配以任何字符开始,以Sp结束的字段值
matches ‘?l*’; 匹配第一个字符任意,第二个字符为l,其余字符任意的字段值
matches ‘[A-N]*’; 匹配以A到N的字符开始,其余字符任意的字段值
matches ‘*[sS]*’; 匹配含有s或S的字段值,扩展以下可用于case insensitive查询
like ‘%/%%’; 匹配含有%的字段值

用SQL语句求表一中的关于name有多少不同的num,结果如表二。
表一:                     表二:
id   name   num              name     count1
1    AA    1               CC       2
2    AA    2               BB       2
3    AA    3               AA       3
4    AA    1
5    AA    2
6    BB    4
7    BB    5
8    BB    4
9    BB    5
10   CC    6
11   CC    6
12   CC    7

SQL语句如下:

create table t1
(
id smallint,
name char(10),
num smallint
);

insert into t1 values(1,'AA',1);
insert into t1 values(2,'AA',2);
insert into t1 values(3,'AA',3);
insert into t1 values(4,'AA',1);
insert into t1 values(5,'AA',2);
insert into t1 values(6,'BB',4);
insert into t1 values(7,'BB',5);
insert into t1 values(8,'BB',4);
insert into t1 values(9,'BB',5);
insert into t1 values(10,'CC',6);
insert into t1 values(11,'CC',6);
insert into t1 values(12,'CC',7);

A:select name ,count(distinct num) from t1 group by name;

4)使用旋转矩阵,将表一中关于id在不同月份的费用,由纵向变为横向。

其中表一对一个id某个月份的记录数可能>;1。表一:
id   d1  fee费用(分)
1 2000-01-24 100
1 2000-04-24 100
2 2000-02-24 200
2 2000-06-24 200
3 2000-04-24 400
4 2000-04-24 400
5 2000-05-24 500
6 2000-06-24 600
7 2000-09-24 900
8 2000-11-24 1100

表二:
id 1月份费用 2月份费用 …… … … 12月份费用
1  100 0  0  100  0  0  0  0  0  0  0   0
2  0  200 0  0   0  200 0  0  0  0  0   0
3  0  0  0  400  0  0  0  0  0  0  0   0
4  0  0  0  400  0  0  0  0  0  0  0   0
5  0  0  0  0   500 0  0  0  0  0  0   0
6  0  0  0  0   0  600 0  0  0  0  0   0
7  0  0  0  0   0  0  0  0  900 0  0   0
8  0  0  0  0   0  0  0  0  0  0  1100  0

SQL语句:
create table t3
(
id smallint,
d1 datetime year to day,
fee int
);

insert into t3 values(1,"2000-01-24", 100);
insert into t3 values(1,"2000-04-24", 100);
insert into t3 values(2,"2000-02-24", 200);
insert into t3 values(2,"2000-06-24", 200);
insert into t3 values(3,"2000-04-24", 400);
insert into t3 values(4,"2000-04-24", 400);
insert into t3 values(5,"2000-05-24", 500);
insert into t3 values(6,"2000-06-24", 600);
insert into t3 values(7,"2000-09-24", 900);
insert into t3 values(8,"2000-11-24", 1100); 

create table t4 –旋转矩阵
(
m_code smallint,
y1 smallint,
y2 smallint,
y3 smallint,
y4 smallint,
y5 smallint,
y6 smallint,
y7 smallint,
y8 smallint,
y9 smallint,
y10 smallint,
y11 smallint,
y12 smallint
);

insert into t4 values(1, 1,0,0,0,0,0,0,0,0,0,0,0);
insert into t4 values(2, 0,1,0,0,0,0,0,0,0,0,0,0);
insert into t4 values(3, 0,0,1,0,0,0,0,0,0,0,0,0);
insert into t4 values(4, 0,0,0,1,0,0,0,0,0,0,0,0);
insert into t4 values(5, 0,0,0,0,1,0,0,0,0,0,0,0);
insert into t4 values(6, 0,0,0,0,0,1,0,0,0,0,0,0);
insert into t4 values(7, 0,0,0,0,0,0,1,0,0,0,0,0);
insert into t4 values(8, 0,0,0,0,0,0,0,1,0,0,0,0);
insert into t4 values(9, 0,0,0,0,0,0,0,0,1,0,0,0);
insert into t4 values(10,0,0,0,0,0,0,0,0,0,1,0,0);
insert into t4 values(11,0,0,0,0,0,0,0,0,0,0,1,0);
insert into t4 values(12,0,0,0,0,0,0,0,0,0,0,0,1);

--方法一
select id,month(d1) month,sum(fee) fei from t3 group by 1,2 into temp aa;
select id,
sum(y1*fei) y1,sum(y2*fei) y2,sum(y3*fei) y3,sum(y4*fei) y4,
sum(y5*fei) y5,sum(y6*fei) y6,sum(y7*fei) y7,sum(y8*fei) y8,
sum(y9*fei) y9,sum(y10*fei) y10,sum(y11*fei) y11,sum(y12*fei) y12
from aa, t4 where aa.month = t4.m_code
group by id order by id

--方法二
select id,
sum(y1*fee) y1,sum(y2*fee) y2,sum(y3*fee) y3,sum(y4*fee) y4,
sum(y5*fee) y5,sum(y6*fee) y6,sum(y7*fee) y7,sum(y8*fee) y8,
sum(y9*fee) y9,sum(y10*fee) y10,sum(y11*fee) y11,sum(y12*fee) y12
from t3, t4 where month(d1) = t4.m_code
group by id order by id

方法一和方法二的结果一样,但有所区别:
方法一中是先对id某个月的钱进行累加,然后进行旋转;
方法二中在表一对一个id某个月份的记录数可能>;1的情况时,先对每条记录进行旋转,然后在累加求和。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息