2007年8月10日星期五
【SQL SERVER】个人认为讲解连接Join 最简单明了的例子
--建表table1,table2:
create table table1(id int,name varchar(10))
create table table2(id int,score int)
insert into table1 select 1,'lee'
insert into table1 select 2,'zhang'
insert into table1 select 4,'wang'
insert into table2 select 1,90
insert into table2 select 2,100
insert into table2 select 3,70
如表
-------------------------------------------------
table1 | table2 |
-------------------------------------------------
id name |id score |
1 lee |1 90 |
2 zhang |2 100 |
4 wang |3 70 |
-------------------------------------------------
以下均在查询分析器中执行
一、外连接
1.概念:包括左向外联接、右向外联接或完整外部联接
2.左连接:left join 或 left outer join
(1)左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。
(2)sql语句
select * from table1 left join table2 on table1.id=table2.id
-------------结果-------------
id name id score
------------------------------
1 lee 1 90
2 zhang 2 100
4 wang NULL NULL
------------------------------
注释:包含table1的所有子句,根据指定条件返回table2相应的字段,不符合的以null显示
3.右连接:right join 或 right outer join
(1)右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
(2)sql语句
select * from table1 right join table2 on table1.id=table2.id
-------------结果-------------
id name id score
------------------------------
1 lee 1 90
2 zhang 2 100
NULL NULL 3 70
------------------------------
注释:包含table2的所有子句,根据指定条件返回table1相应的字段,不符合的以null显示
4.完整外部联接:full join 或 full outer join
(1)完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
(2)sql语句
select * from table1 full join table2 on table1.id=table2.id
-------------结果-------------
id name id score
------------------------------
1 lee 1 90
2 zhang 2 100
4 wang NULL NULL
NULL NULL 3 70
------------------------------
注释:返回左右连接的和(见上左、右连接)
二、内连接
1.概念:内联接是用比较运算符比较要联接列的值的联接
2.内连接:join 或 inner join
3.sql语句
select * from table1 join table2 on table1.id=table2.id
-------------结果-------------
id name id score
------------------------------
1 lee 1 90
2 zhang 2 100
------------------------------
注释:只返回符合条件的table1和table2的列
4.等价(与下列执行效果相同)
A:select a.*,b.* from table1 a,table2 b where a.id=b.id
B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件只能用where,不能用on)
三、交叉连接(完全)
1.概念:没有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)
2.交叉连接:cross join (不带条件where...)
3.sql语句
select * from table1 cross join table2
-------------结果-------------
id name id score
------------------------------
1 lee 1 90
2 zhang 1 90
4 wang 1 90
1 lee 2 100
2 zhang 2 100
4 wang 2 100
1 lee 3 70
2 zhang 3 70
4 wang 3 70
------------------------------
注释:返回3*3=9条记录,即笛卡尔积
4.等价(与下列执行效果相同)
A:select * from table1,table2
【SQL SERVER】深入浅出SQL教程之SELECT语句表连接
为了从两个或多个表中选出数据,我们一般使用表连接来实现这个功能。 本节介绍join(连接)的概念. 为此我们准备了两个试验用表: album(专辑表) 和 track(曲目表).
为了从两个或多个表中选出数据,我们一般使用表连接来实现这个功能。
本节介绍join(连接)的概念. 为此我们准备了两个试验用表: album(专辑表) 和 track(曲目表).
专辑表:包含200首来自Amazon的音乐CD的概要信息。
album(asin, title, artist, price, release, label, rank) |
曲目表:每张专辑中的曲目(因为是音乐CD,所以也可叫歌曲)的详细信息。
track(album, dsk, posn, song) |
SQL短语 FROM album JOIN track ON album.asin=track.album 表示连接album和track表。
其中,album.asin表示专辑的惟一标识号,track.album表示曲目表中和专辑关联的专辑号。
连接后,得到一个临时表,该临时表中每条记录包含的字段由两部分组成,
除了专辑表中的对应字段album(title, artist ...),还包含曲目表的所有字段track(album, disk, posn and song)。
有了这张临时表,很多查询就容易实现了。
看看一些具体的实例,
一、列出歌名为'Alison'的专辑名称和作者
SELECT title, artist FROM album JOIN track ON (album.asin=track.album) WHERE song = 'Alison' |
显然,歌名、专辑名称和作者分别在两个表中,必需使用表连接来完成这个查询。
二、哪个artist录制了歌曲'Exodus'
SELECT artist FROM album JOIN track ON (asin=album) WHERE song = 'Exodus' |
用作连接的两个字段asin,album因为在两个表中都是惟一的,所以不一定要加表名作为前缀。
但为了方便理解,建议使用前缀,形如:album.asin=track.album
三、列出曲目表中所有属于'Blur'专辑的歌曲
SELECT song FROM album JOIN track ON (asin=album) WHERE title = 'Blur' |
如果我们把 album JOIN track ON (asin=album) 看成一个临时表的话,join的概念就很好理解了。
上节我们介绍了表连接,更确切的说是inner joins內连接.
內连接仅选出两张表中互相匹配的记录.因此,这会导致有时我们需要的记录没有包含进来。
为更好的理解这个概念,我们介绍两个表作演示。苏格兰议会中的政党表(party)和议员表(msp)。
party(Code,Name,Leader)
Code: 政党代码
Name: 政党名称
Leader: 政党领袖
msp(Name,Party,Constituency)
Name: 议员名
Party: 议员所在政党代码
Constituency: 选区
在介绍左连接、右连接和全连接前,有一个数据库中重要的概念要介绍一下,即空值(NULL)。
有时表中,更确切的说是某些字段值,可能会出现空值, 这是因为这个数据不知道是什么值或根本就不存在。
空值不等同于字符串中的空格,也不是数字类型的0。因此,判断某个字段值是否为空值时不能使用=,<>这些判断符。必需有专用的短 语:IS NULL 来选出有空值字段的记录,同理,可用 IS NOT NULL 选出不包含空值的记录。
例如:下面的语句选出了没有领导者的政党。(不要奇怪,苏格兰议会中确实存在这样的政党)
SELECT code, name FROM party WHERE leader IS NULL |
又如:一个议员被开除出党,看看他是谁。(即该议员的政党为空值)
SELECT name FROM msp WHERE party IS NULL |
好了,让我们言归正传,看看什么叫左连接、右连接和全连接。
A left join(左连接)包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录。
同理,也存在着相同道理的 right join(右连接),即包含所有的右边表中的记录甚至是左边表中没有和它匹配的记录。
而full join(全连接)顾名思义,左右表中所有记录都会选出来。
讲到这里,有人可能要问,到底什么叫:包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录。
我们来看一个实例:
SELECT msp.name, party.name FROM msp JOIN party ON party=code |
这个是我们上一节所学的Join(注意:也叫inner join),这个语句的本意是列出所有议员的名字和他所属政党。
很遗憾,我们发现该查询的结果少了两个议员:Canavan MSP, Dennis。为什么,因为这两个议员不属于任何政党,即他们的政党字段(Party)为空值。那么为什么不属于任何政党就查不出来了?这是因为空值在作 怪。因为议员表中政党字段(Party)的空值在政党表中找不到对应的记录作匹配,即FROM msp JOIN party ON party=code 没有把该记录连接起来,而是过滤出去了。
在该短语中,msp在Join的左边,所有称为左表。party在Join的右边,所有称为右表。
现在再看看这句话,"包含所有的左边表中的记录甚至是右边表中没有和它匹配的记录",意思应该很明白了吧。执行下面这个语句,那两个没有政党的 议员就漏不了了。
SELECT msp.name, party.name FROM msp LEFT JOIN party ON party=code |
关于右连接,看看这个查询就明白了:
SELECT msp.name, party.name FROM msp RIGHT JOIN party ON msp.party=party.code |
这个查询的结果列出所有的议员和政党,包含没有议员的政党,但不包含没有政党的议员。 那么既要包含没有议员的政党,又要包含没有政党的议员该怎么办呢,对了,全连接(full join)。
SELECT msp.name, party.name
FROM msp FULL JOIN party ON msp.party=party.code
【SQL SERVER】SQLl内、外、左、右连接
SELECT COLUMN_NAME,C O L U M N _ N A M E [ , . . . n ]
FROM TA B L E _ N A M E,TA B L E _ N A M E [ , . . . n ]
WHERE TABLE_NAME.COLUMN_NAME JOIN_OPERATOR TA B L E _ N A M E . C O L U M N _ N A M E
上述的连接操作符(J O I N _ O P E R ATO R)可以是:=、>、<、> =、< =、! =、< >、! >、! <、= *、* =。
在A N S I中,"="连接应该写成Inner Join;"* ="连接应该写成LEFT OUT JOIN;"= *"连接应该写成" RIGHT OUT JOIN"。
在SQL SERVER中,这些写法都可以用。但是,A N S I规定的写法是INNER JOIN等标志。一般而言,在任何连接中,都使用"主键=外键"的连接查询条件。
---------------------------------------------------------------------------------
非限制连接(CROSS JOIN),就是指不带W H E R E子句的查询。在数学上,就是表的笛卡尔积。若R表和S表非限制连接,而且R表有X行,S表有Y行,那么结果集是X * Y行。即:R表的一行对应着S表的所有行。在应用中,非限制连接产生的是无意义结果集,但在数据库的数学模式上有重要的作用。
-------------------------------------------------------------------------
自然连接(INNER JOIN)也叫内连接。我们先看下面的例子:
SELECT PUB_NAME,TITLE
FROM TITLES,PUBLISHERS
WHERE TITLES.PUB_ID=PUBLISHERS.PUB_ID
或写成:
SELECT PUB_NAME,TITLE
FROM TITLES INNER JOIN PUBLISHERS
ON TITLES.PUB_ID=PUBLISHERS.PUB_ID
其中,INNER JOIN是SQL Server的缺省连接,可简写为J O I N。在J O I N后面指定哪些表作连接。O N后面指定了连接的条件。
以上操作的过程如下:
1) 从T I T L E S表中取出一条符合其条件的记录。
2) 扫描P U B L I S H E R S表,分别检查每条记录是否在连接属性上同表T I T L E S取出的记录相
3) 相等就显示信息。继续从表T I T L E S中取下一条记录,重复步骤2。其实,两个或多个表要做连接,那么这些表之间必然存在着主键和外键的关系。所以,只需要将这些键的关系列出,就可以得出表 连接的结果。如上例中, P U B _ I D是P U B L I S H E R S表的主键, P U B_ I D又是TI T L E S表的外键,参照P U B L I S H E R S表中的P U B _ I D .所以,这两个表的连接条件就是T I T L E S.PUB_ID=PUBLISHERS. PUB_ID。
-----------------------------------------------------------------------
外连接(OUTER JOIN)允许限制一张表中的行,而不限制另一张表中的行。
下面举两个例子来说明外连接的用法。请比较这两个例子。
例显示所有的书名(无销售记录的书也包括在内,"*"在左边表示不限制左边表的数
SELECT TITLES.TITLE_ID,title=convert(char(38),TITLE),QTY
FROM TITLES,SALES
WHERE TITLES.TITLE_ID *= SALES.TITLE_ID
或写为:
SELECT TITLES.TITLE_ID,title=convert(char(38),TITLE),QTY
FROM TITLES LEFT OUTER JOIN SALES
ON TITLES.TITLE_ID = SALES.TITLE_ID
外连接的方法有两种:
• A *= B 包括第一张表A的所有行在内,而不考虑语句限制(如: A . t i t l e _ i d = B . t i t l e _ i d)。
相当于LEFT OUT JOIN。
• A =* B 包括第二张表B的所有行在内,而不考虑语句限制(如: A . t i t l e _ i d = B . t i t l e _ i d)。
相当于RIGHT OUT JOIN。
创建外连接规则:
1) 外连接显示外部表中的所有行,包括与相关表不相配的行在内。
2) 外连接只能在两张表之间进行。
3) 不能在内部表上使用IS NULL检索条件。
2007年8月9日星期四
【SQL SERVER】获得数据库对象的方法探讨
取得数据库名的方法
系统存储过程sp_helpdb
或者
USE master
SELECT sysdb.name AS dbname, xlogin.name AS owner FROM sysdatabases AS sysdb LEFT JOIN sysxlogins AS xlogin ON sysdb.sid = xlogin.sid
sp_helpdb获得的内容更准确:第二种方式无法获取Windows NT登陆用户。
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的用户表:
USE DBAudit
SELECT sysobjects.name AS tname, sysusers.name AS owner FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'U'
获取指定数据库的系统表:
USE DBAudit
SELECT sysobjects.name AS tname, sysusers.name AS owner FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'S'
或者统一使用:
USE DBAudit
SELECT sysobjects.name AS name, sysusers.name AS owner, type, sysobjects.id AS id FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'U' OR type = 'S'
注:
sysobjects中type字段类型解释:
C = CHECK 约束
D = 默认值或 DEFAULT 约束
F = FOREIGN KEY 约束
L = 日志
FN = 标量函数
IF = 内嵌表函数
P = 存储过程
PK = PRIMARY KEY 约束(类型是 K)
RF = 复制筛选存储过程
S = 系统表
TF = 表函数
TR = 触发器
U = 用户表
UQ = UNIQUE 约束(类型是 K)
V = 视图
X = 扩展存储过程
系统存储过程
USE xxxDatabase
EXEC sp_help xxxTable
或者
USE xxxDatabase
SELECT syscolumns.name AS name, systypes.name AS type FROM syscolumns LEFT JOIN systypes ON syscolumns.xtype = systypes.xtype WHERE syscolumns.id = xxxTableId
这两种方法都可以取得包括视图的列。
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的视图:
USE DBAudit
SELECT sysobjects.name AS name, sysusers.name AS owner FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'V'
获取指定数据库的视图的内容:
EXEC sp_helptext xxxObject
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的存储过程或者扩展存储过程:
USE DBAudit
SELECT sysobjects.name AS name, sysusers.name AS owner, type FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'P' OR type = 'X'
获取指定数据库的存储过程或者扩展存储过程的内容:
EXEC sp_helptext xxxObject
无法获取加密的存储过程。扩展存储过程只能得到dll程序名。
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的各种函数(内嵌函数等):
USE DBAudit
SELECT sysobjects.name AS name, sysusers.name AS owner, type FROM sysobjects LEFT JOIN sysusers ON sysobjects.uid = sysusers.uid WHERE type = 'FN' OR type = 'IF' OR type = 'TF'
获取指定数据库的函数的内容:
EXEC sp_helptext xxxObject
只能获取用户定义的函数内容。
系统存储过程
USE xxx
EXEC sp_helptrigger xxxTable
或者
获取指定数据库的表的触发器:
SELECT sysobj1.name AS name, sysusers.name AS owner FROM sysobjects AS sysobj1 LEFT JOIN sysobjects AS sysobj2 ON sysobj1.parent_obj = sysobj2.id LEFT JOIN sysusers ON sysobj1.uid = sysusers.uid WHERE sysobj1.type = 'TR'AND sysobj2.name = 'xxxTable'
系统存储过程
USE xxx
EXEC sp_helpindex xxxTable
系统存储过程
USE xxx
EXEC sp_helpuser
系统存储过程
USE xxx
EXEC sp_helprole
Ø ORACLE只能连接特定数据库,不能自动扫描数据库对象。
Ø ORACLE表必须用用户来区别,否则表可能重名。
Ø ORACLE不能区别系统表或者是用户表,因此只能由管理员选择扫描某些特定用户的表。
只能由用户指定数据库,不能自动扫描到特定数据库服务器上的所有数据库。
存储数据库表的系统表/视图主要有:
DBA_ALL_TABLES
描述数据库中所有的对象以及相关的表。
ALL_ALL_TABLES
描述数据库中所有的用户可以访问的对象以及相关的表。
USER_ALL_TABLES
描述数据库中当前用户拥有的对象以及相关的表。
DBA_ TABLES
描述数据库中所有相关的表。
ALL_ TABLES
描述数据库中所有的用户可以访问的相关的表。
USER_ TABLES
描述数据库中当前用户拥有的相关的表。
因此,可以从ALL_TABLES中取得隶属于指定用户的表:
SELECT TABLE_NAME FROM SYS.ALL_TABLES WHERE OWNER = 'DBAUDIT';
取得隶属于指定表空间的表:
SELECT TABLE_NAME FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME = 'DBAUDIT';
也可以不指定用户名,从而取得所有的表。
SELECT TABLE_NAME FROM SYS.ALL_TABLES;
存储数据库表的列属性的系统表/视图主要有:
DBA_TAB_COLUMNS
描述数据库中所有的表的列属性。
ALL_TAB_COLUMNS
描述数据库中所有的用户可以访问的表的列属性。
USER_TAB_COLUMNS
描述数据库中当前用户拥有的表的列属性。
ALL_TAB_COLS
描述数据库中所有的用户可以访问的表的列属性。
因此,可以从ALL_TAB_COLUMNS中取得隶属于指定用户的表:
SELECT COLUMN_NAME FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME = 'TASK' AND OWNER = 'DBAUDIT';
存储数据库视图的系统表/视图主要有:
DBA_VIEWS
描述数据库中所有的视图的属性。
ALL_VIEWS
描述数据库中所有的用户可以访问的视图的属性。
USER_VIEWS
描述数据库中所有的当前用户拥有视图的属性。
因此,可以从ALL_VIEWS中取得隶属于指定用户的视图:
SELECT VIEW_NAME FROM SYS.ALL_VIEWS WHERE OWNER = 'DBAUDIT';
存储系统对象的系统表/视图有:
DBA_OBJECTS
描述数据库中所有的对象。
ALL_OBJECTS
描述数据库中所有的可以访问的对象。
USER_OBJECTS
描述数据库中所有的当前用户拥有的对象。
SYS_OBJECTS
描述数据库中所有的系统对象。?
对象类型有:
CONSUMER GROUP
CONTEXT
DIRECTORY
FUNCTION
INDEX
INDEX PARTITION
INDEXTYPE
JAVA CLASS
JAVA DATA
JAVA RESOURCE
JAVA SOURCE
LIBRARY
LOB
MATERIALIZED VIEW
OPERATOR
PACKAGE
PACKAGE BODY
PROCEDURE
QUEUE
SEQUENCE
SYNONYM
TABLE
TABLE PARTITION
TRIGGER
TYPE
TYPE BODY
VIEW
因此,取得存储过程可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PROCEDURE';
取得隶属于某个用户的存储过程可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PROCEDURE' AND OWNER = 'DBAUDIT';
同样,取得其他的对象也可以用这个方法,包括表,视图等。
取得存储过程内容的方法
对象类型为类型、类型体、过程、函数、包、包体,JAVA源代码的所有对象的源代码都存储在几个系统表/视图中:
DBA_SOURCE
存储所有数据库对象的源代码。
ALL_SOURCE
存储所有可以访问的数据库对象的源代码。
USER_SOURCE
存储所有当前用户拥有的数据库对象的源代码。
因此,取得存储过程源代码的方法:
SELECT TEXT FROM SYS.ALL_SOURCE WHERE NAME = 'XXX' AND TYPE = 'PROCEDURE';
同上,取得函数可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'FUNCTION';
取得隶属于某个用户的函数可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'FUNCTION' AND OWNER = 'DBAUDIT';
取得函数内容可以用:
SELECT TEXT FROM SYS.ALL_SOURCE WHERE NAME = 'XXX' AND TYPE = 'FUNCTION';
存储数据库触发器的系统表/视图主要有:
DBA_TRIGGERS
描述数据库中所有的触发器的属性。
ALL_ TRIGGERS
描述数据库中所有的用户可以访问的触发器的属性。
USER_ TRIGGERS
描述数据库中所有的当前用户拥有触发器的属性。
因此,可以从ALL_ TRIGGERS中取得隶属于指定用户的触发器:
SELECT TRIGGER_NAME FROM SYS.ALL_TRIGGERS WHERE OWNER = 'DBAUDIT';
取得触发器内容的方法:
SELECT TRIGGER_BODY FROM SYS.ALL_TRIGGERS WHERE TRIGGER_NAME = 'XXX';
存储数据库索引的系统表/视图主要有:
DBA_INDEXES
描述数据库中所有的索引的属性。
ALL_ INDEXES
描述数据库中所有的用户可以访问的索引的属性。
USER_ INDEXES
描述数据库中所有的当前用户拥有索引的属性。
因此,可以从ALL_ INDEXES中取得隶属于指定用户的索引:
SELECT INDEX_NAME,TABLE_NAME FROM SYS.ALL_INDEXES WHERE OWNER = 'DBAUDIT';
取得索引相关的列的方法:
SELECT COLUMN_NAME FROM SYS.ALL_IND_COLUMNS WHERE INDEX_NAME = 'XXX' AND TABLE_OWNER = 'DBAUDIT';
存储数据库用户的系统表/视图主要有:
DBA_USERS
描述数据库中所有的用户的属性。
ALL_USERS
描述数据库中所有的用户的属性。
USER_USERS
描述数据库中当前用户的属性。
因此,可以从ALL_USERS中取得用户:
SELECT USER_ID, USERNAME FROM SYS.ALL_USERS;
存储角色的表/视图有:
DBA_ROLES
描述数据库中所有角色。
取得角色方法:
SELECT ROLE FROM SYS.DBA_ROLES;
SELECT TABLESPACE_NAME FROM SYS.DBA_TABLESPACES;
SELECT FILE_NAME, FILE_ID, TABLESPACE_NAME FROM SYS.DBA_DATA_FILES;
存储数据库连接的系统表/视图主要有:
DBA_LINKS
描述数据库中所有的连接的属性。
ALL_LINKS
描述数据库中所有的用户可访问的连接的属性。
USER_LINKS
描述数据库中当前用户的连接属性。
因此,可以从DBA_DB_LINKS中取得连接:
SELECT * FROM SYS.DBA_DB_LINKS;
SELECT * FROM SYS.ALL_SYNONYMS WHERE TABLE_OWNER = 'DBAUDIT';
取得程序包可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE';
取得隶属于某个用户的程序包可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE' AND OWNER = 'DBAUDIT';
取得程序包内容可以用:
SELECT TEXT FROM SYS.ALL_SOURCE WHERE NAME = 'XXX' AND TYPE = 'PACKAGE';
取得程序包体可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE BODY';
取得隶属于某个用户的程序包可以用:
SELECT OBJECT_NAME FROM SYS.ALL_OBJECTS WHERE OBJECT_TYPE = 'PACKAGE BODY ' AND OWNER = 'DBAUDIT';
取得程序包内容可以用:
SELECT TEXT FROM SYS.ALL_SOURCE WHERE NAME = 'XXX' AND TYPE = 'PACKAGE BODY ';
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
暂不扫描。
系统存储过程sp_helpdb
或者
USE master
SELECT d.name dbname, u.name owner FROM sysdatabases d, sysusers u WHERE d.suid = u.suid
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的用户表:
USE DBAudit
SELECT sysobjects.name AS tname, sysusers.name AS owner FROM sysobjects, sysusers WHERE sysobjects.uid = sysusers.uid AND type = 'U'
获取指定数据库的系统表:
USE DBAudit
SELECT sysobjects.name AS tname, sysusers.name AS owner FROM sysobjects, sysusers WHERE sysobjects.uid = sysusers.uid AND type = 'S'
或者统一使用:
USE DBAudit
SELECT sysobjects.name AS tname, sysusers.name AS owner FROM sysobjects, sysusers WHERE sysobjects.uid = sysusers.uid AND (type = 'U' OR type = 'S')
注:
sysobjects中type字段类型解释:
C = CHECK 约束
D = 默认值或 DEFAULT 约束
F = FOREIGN KEY 约束
L = 日志
FN = 标量函数
IF = 内嵌表函数
P = 存储过程
PK = PRIMARY KEY 约束(类型是 K)
RF = 复制筛选存储过程
S = 系统表
TF = 表函数
TR = 触发器
U = 用户表
UQ = UNIQUE 约束(类型是 K)
V = 视图
X = 扩展存储过程
系统存储过程
USE xxxDatabase
EXEC sp_help xxxTable
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的视图:
USE xxx
SELECT sysobjects.name AS name, sysusers.name AS owner FROM sysobjects, sysusers WHERE sysobjects.uid = sysusers.uid AND type = 'V'
获取指定数据库的视图的内容:
EXEC sp_helptext xxxObject
系统存储过程
USE xxx
EXEC sp_help
或者
获取指定数据库的存储过程或者扩展存储过程:
USE xxx
SELECT sysobjects.name name, sysusers.name owner FROM sysobjects, sysusers WHERE sysobjects.uid = sysusers.uid AND (type = 'P' OR type = 'X')
获取指定数据库的存储过程或者扩展存储过程的内容:
EXEC sp_helptext xxxObject
无法获取加密的存储过程。扩展存储过程只能得到dll程序名。
Sybase不支持用户定义函数。
获取指定数据库的表的触发器:
系统存储过程
USE xxx
EXEC sp_helpindex xxxTable
系统存储过程
USE xxx
EXEC sp_helpuser
Ø DB2只能连接特定数据库,不能自动扫描数据库对象。
Ø DB2表必须用用户来区别,否则表可能重名。
Ø DB2不能区别系统表或者是用户表,因此只能由管理员选择扫描某些特定用户的表。
只能由用户指定数据库,不能自动扫描到特定数据库服务器上的所有数据库。
SELECT NAME, CREATOR FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'
或者
SELECT TABNAME, TABSCHEMA FROM SYSCAT.TABLES WHERE TYPE = 'T'
SELECT NAME, COLTYPE FROM SYSIBM.SYSCOLUMNS WHERE TBNAME = 'SYSTABLES' AND TBCREATOR = 'SYSIBM'
或者
SELECT COLNAME, TYPENAME FROM SYSCAT.COLUMNS WHERE TABNAME = 'SYSTABLES' AND TABSCHEMA = 'SYSIBM'
SELECT NAME, CREATOR FROM SYSIBM.SYSTABLES WHERE TYPE = 'V'
或者
SELECT NAME, CREATOR FROM SYSIBM.SYSVIEWS
或者
SELECT TABNAME, TABSCHEMA FROM SYSCAT.TABLES WHERE TYPE = 'V'
或者
SELECT VIEWNAME, VIEWSCHEMA FROM SYSCAT.VIEWS
取得内容的方法
SELECT TEXT FROM SYSCAT.VIEWS WHERE VIEWNAME = 'VIEWS' AND VIEWSCHEMA = 'SYSCAT'
SELECT PROCNAME, PROCSCHEMA FROM SYSIBM.SYSPROCEDURES
取得存储过程内容的方法
SELECT TEXT FROM SYSIBM.SYSPROCEDURES WHERE PROCNAME = 'XXX' AND PROCSCHEMA = 'YYY'
SELECT NAME, SCHEMA FROM SYSIBM.SYSFUNCTIONS
取得函数内容可以用:
SELECT NAME, SCHEMA FROM SYSIBM.SYSTRIGGERS WHERE TBNAME = 'SYSTABLES' AND TBCREATOR = 'SYSIBM'
或者
SELECT TRIGNAME, TRIGSCHEMA FROM SYSCAT.TRIGGERS WHERE TABNAME = 'SYSTABLES' AND TABSCHEMA = 'SYSIBM'
取得触发器内容的方法:
SELECT TEXT FROM SYSIBM.SYSTRIGGERS WHERE NAME = 'XXX' AND SCHEMA = 'YYY '
SELECT NAME, CREATOR, COLNAMES FROM SYSIBM.SYSINDEXES WHERE TBNAME = 'SYSTABLES' AND TBCREATOR = 'SYSIBM'
或者
SELECT INDNAME, INDSCHEMA, COLNAMES FROM SYSCAT.INDEXES WHERE TABNAME = 'SYSTABLES' AND TABSCHEMA = 'SYSIBM'
SELECT GRANTEE FROM SYSIBM.SYSDBAUTH WHERE GRANTEETYPE = 'U'
或者
SELECT GRANTEE FROM SYSCAT.DBAUTH WHERE GRANTEETYPE = 'U'
DB2只有用户组的概念。
SELECT GRANTEE FROM SYSIBM.SYSDBAUTH WHERE GRANTEETYPE = 'G'
或者
SELECT GRANTEE FROM SYSCAT.DBAUTH WHERE GRANTEETYPE = 'G'
SELECT TBSPACE FROM SYSCAT.TABLESPACES
DATABASE sysmaster
SELECT name, owner FROM sysdatabases
获取指定数据库的表:
DATABASE xxx
SELECT tabname, owner, tabid FROM systables WHERE tabtype = 'T'
注:
tabid 为0-24为系统表,100-xxx为用户表。
tabtype字段类型解释:
T = 用户表
V = 视图
P = 私有同义词
S = 同义词
DATABASE xxxDatabase
SELECT c.colname, c.coltype FROM syscolumns c, systables t WHERE c.tabid = t.tabid AND t.tabname = 'xxxTable'
可以取得包括视图的列。
注:
coltype 字段意义:
0 = CHAR 8 = MONEY
2 = INTEGER 11 = BYTE
3 = FLOAT 12 = TEXT
4 = SMALLFLOAT 13 = VARCHAR
5 = DECIMAL 14 = INTERVAL
6 = SERIAL 15 = NCHAR
7 = DATE 16 = NVARCHAR
DATABASE xxx
SELECT tabname, owner FROM systables WHERE tabtype = 'V'
取得视图内容:
SELECT v.viewtext FROM sysviews v, systables t WHERE v.tabid = t.tabid AND t.tabname = 'xxxTable'
获取指定数据库的存储过程:
DATABASE xxx
SELECT procname, owner FROM sysprocedures
获取指定数据库的存储过程的内容:
SELECT b.data FROM sysprocbody b, sysprocedures p WHERE b.procid = p.procid AND p.procname = 'systdist' AND datakey = 'T'
Informix不支持用户定义函数?
获取指定数据库的表的触发器:
SELECT g.trigname, g.owner, g.event FROM systriggers g, systables t WHERE g.tabid = t.tabid AND t.tabname = 'xxxTable'
取得触发器内容:
SELECT b.data FROM systrigbody b, systriggers g WHERE b.trigid = g.trigid AND g.trigname = '%s' AND datakey = 'D'
获取指定数据库的表的触发器:
SELECT i.idxname FROM sysindexes i, systables t WHERE i.tabid = t.tabid AND t.tabname = 'xxxTable'