網上已經有很多SQL與ORACLE的對比 ,但本人要講的即不是單純的SQL,也不是單純的Oracle,更不是評價誰好誰壞(意思不大),而是兩種數據庫之相同和異同,本人曾講授過SQL與ORACLE的課程,講SQL時說SQL好,講ORACLE時又說Oracle棒,現在終於可以平心而評啦。
估計有人現在會嘿嘿冷笑(又一個誤人子弟的騙子),老實說,當初每次講完課,就有這種感覺—教的人不得其法,學的人不得其道。說點嚴肅的事吧,據說比爾與艾裡森在洗手間相遇,兩個又是擁抱,又是KISS,不多久就吵了起來,比爾對查詢分析器(SQL QUERY ANALYZE)贊不經絕口,艾裡森嘿嘿冷笑,只說了一句話—SQL PLUS內秀。
言歸正傳,且聽我一一道來
001、SQL與Oracle的內存分配
Oracle的內存分配大部分是由INIT.ORA來決定的,一個數據庫實例可以有N種分配方案,不同的應用(OLTP、OLAP)它的配置是有側重的。SQL概括起來說,只有兩種內存分配方式:動態內存分配與靜態內存分配,動態內存分配充許SQL自己調整需要的內存,靜態內存分配限制了SQL對內存的使用。
002、SQL與Oracle的物理結構
總得講,它們的物理結構很相似,SQL的數據庫相當於ORACLE的模式(方案),SQL的文件組相當於ORACLE的表空間,作用都是均衡DISK I/O,SQL創建表時,可以指定表在不同的文件組,Oracle則可以指定不同的表空間。
CREATE TABLE A001(ID DECIMAL(8,0)) ON [文件組]
--------------------------------------------------------------------------------------------
CREATE TABLE A001(ID NUMBER(8,0)) TABLESPACE 表空間
注:以後所有示例,先SQL,後Oracle
003、SQL與Oracle的日志模式
SQL對日志的控制有三種恢復模型:SIMPLE、FULL、BULK-LOGGED;ORACLE對日志的控制有二種模式:NOARCHIVELOG、ARCHIVELOG。SQL的SIMPLE相當於ORACLE的NOARCHIVELOG,FULL相當於ARCHIVELOG,BULK-LOGGED相當於Oracle大批量數據裝載時的NOLOGGING。經常有網友抱怨SQL的日志龐大無比且沒法處理,最簡單的辦法就是先切換到SIMPLE模式,收縮數據庫後再切換到FULL,記住切換到FULL之後要馬上做完全備份。
004、SQL與Oracle的備份類型
SQL的備份類型分的極雜:完全備份、增量備份、日志備份、文件或文件組備份;ORACLE的備份類型就清淅多啦:物理備份、邏輯備份;ORACLE的邏輯備份(EXP)相當於SQL的完全備份與增量備份,ORACLE的物理備份相當於SQL的文件與文件組備份。SQL的各種備份都密切相關,以完全備份為基礎,配合其它的備份方式,就可以靈活地備分數據;ORACLE的物理備份與邏輯備份各司其職。SQL可以有多個日志,相當於ORACLE日志組,Oracle的日志自動切換並歸檔,SQL的日志不停地膨脹……SQL有附加數據庫,可以將數據庫很方便地移到別一個服務器,Oracle有可傳輸表空間,可操作性就得注意啦。
005、SQL與Oracle的恢復類型
SQL有完全恢復與基於時間點的不完全恢復;Oracle有完全恢復與不完全恢復,不完全恢復有三種方式:基於取消的、基於時間的、基於修改的(SCN)的恢復。不完全恢復可以恢復數據到某個穩定的狀態點。
006、SQL與Oracle的事務隔離
SET TRANSACTION ISOLATION LEVEL
SQL有四種事務隔離級別:
READ COMMITTED、READ UNCOMMITTED、REPEATABLE READ、SERIALIZABLE
Oracle有兩種事務隔離級別
READ COMMITTED、SERIALIZABLE
SQL雖然有四種事務隔離,事務之間還是經常發生阻塞;ORACLE則利用回退段很好地實現了事務隔離,不會產生阻塞。SQL與Oracle如果發生死鎖,都可以很快地識別並將之處理掉。
007 SQL與Oracle的外鍵約束
SQL的外鍵約束可以實現級聯刪除與級聯更新,Oracle則只充許級聯刪除。
CREATE TABLE A001(ID INT PRIMARY KEY,NAME VARCHAR(20))
CREATE TABLE A002(ID INT REFERENCES A001(ID)ON DELETE CASCADE ON UPDATE CASCADE,AGE TINYINT)
CREATE TABLE A001(ID INT PRIMAY KEY,NAME VARCHAR2(20))
CREATE TABLE A002(ID INT REFERENCES A001(ID)ON DELETE CASCADE,AGE NUMBER(2,0))
008、SQL與Oracle的臨時表
SQL的臨時表用#或##開頭,使用完後自動釋放,Oracle的臨時表則存在數據庫中,每個會話的數據都互不干涉。Oracle臨時表中的紀錄可以被定義為自動刪除(分commit方式和transaction方式),而表結構不會被自動刪除。臨時表的DML,DDL操作和標准表一樣。
CREATE TABLE #TEMP(ID INT,NAME VARCHAR(20))
-------------------------------------------------------
CREATE GLOBAL TEMPORARY TABLE TEMP(ID INT,VARCHAR2(20))
009、SQL與Oracle的類型轉換
SQL常用類型轉換函數有:CAST、CONVERT、STR
Oracle常用類型轉換函數有:TO_CHAR、TO_NUMBER、TO_DATE
SELECT CONVERT(VARCHAR(20),GETDATE(),112)
------------------------------------------------------------------------------------------------
SELECT TO_CHAR(SYSDATE,‘YYYYMMDD’)FROM DUAL
010、SQL與Oracle的自動編號
SQL的編號一般由IDENTITY字段來提供,可以靈活地設定種子值,增量,取值范圍有BIGINT、INT、SMALLINT、TINYINT、DEIMAL等;Oracle的編號一般由SEQUENCE來提供,由NEXTVAL與CURVAL函數從SEQUENCES取值。
CREATE TABLE A003(ID INT IDENTITY(-9999,9),NAME VARCHAR(20))
-------------------------------------------------------------------------------------------------------
CREATE SEQUENCE SEQ_001 START 9999 INCREMENT BY 9
CREATE TABLE A004(ID INT)
INSERT INTO A004 VALUES(SEQ_001.NEXTVAL)
INSERT INTO A004 VALUES(SEQ_001.CURVAL+1)
011、SQL與Oracle的分區表
從嚴格意思上來講,SQL還沒有分區表,它的分區表是以UNION為基礎,將多個結果集串起來,實際上是視圖;ORACLE的分區表有多種:PARTITION BY RANGE、PARTITION BY HASH、PARTITION BY LIST,其它就是混合分區,以上三種基礎分區的混合使用。當然Oracle也可以象SQL那樣分區視圖。
CREATE TABLE A1999(ID INT,NAME VARCHAR(20))
CREATE TABLE A2000(ID INT,NAME VARCHAR(20))
CREATE VIEW V_PART AS
SELECT * FROM A1999 UNION SELECT * FROM A2000
--------------------------------------------------
CREATE TABLE A_PART1(ID INT,NAME VARCHAR2(20))
PARTITON BY RANGE(ID)(
PARTITION P1 VALUES LESS THEN (2000000) PATITION P2 VALUES LESS THEN (MAXVALUE))
CREATE TABLE A_PART2(ID INT,NAME VARCHAR2(20))
PARTITION BY HASH(ID) PARTITIONS 2 STORE IN (USERS01,USERS02)
CREATE TABLE A_PART3(ID INT,
NAME VARCHAR2(20))
在刪除表時還在表名上加了一對中括號,即使用表名含有空格鍵或其它特殊這符也可以順利刪除。
/>END
---------------------------------------------------------
DECLARE
C VARCHAR2(20);
BEGIN
FOR I IN 1 .. 999 LOOP
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE,''YYYYMMDD'')||LPAD(I,4,''0''));
END LOOP;
END;
說明 雖然都可以實現,但Oracle的LPAD果然身手不凡,可憐的MS還沒有類似LPAD的函數,只有用CASE進行判斷組合,真得很蠢,如果你有好的辦法,請明示,甚至連循環結構,SQL稍也不慎,就死循環啦(如果注釋掉加藍顯示那條語句的話)。
27、關於SQL與Oracle的分布式結構
SQL在分布式方面做得不錯,不僅提供了鏈接服務器的方式供初級用戶使用,還提供了OPENDATASOURCE、OPENXML、OPENQUERY、OPENROWSET等行集函數,可以方便地通過SQL語句從*.TXT、*.XLS、*.XML、*.MDB、*.DBF等介質獲取數據,還可以從ORACLE、DB2、Sybase等數據庫獲取數據;Oracle在同構數據庫之間提供了DB LINK,異構數據庫之間提供了透明網關軟件。
28、現在有三個表,結構如下
Score(FScoreId 成績記錄號,FSubID 課程號,FStdID 學生號,FScore 成績)
student:(FID 學生號,FName 姓名)
subject:(FSubID 課程號,FSubName 課程名),
怎麼能實現這個表:
姓名 英語 數學 語文 歷史
張薩 78 67 89 76
王強 89 67 84 96
李三 70 87 92 56
李四 80 78 97 66
SELECT A.FNAME AS 姓名,
英語 = SUM(CASE B.FSUBNAME WHEN ''英語'' THEN C.FSCORE END),
數學 = SUM(CASE B.FSUBNAME WHEN ''數學'' THEN C.FSCORE END),
語文 = SUM(CASE B.FSUBNAME WHEN ''語文'' THEN C.FSCORE END),
歷史 = SUM(CASE B.FSUBNAME WHEN ''歷史'' THEN C.FSCORE END)
FROM STUDENT A, SUBJECT B, SCORE C
WHERE A.FID = C.FSTDID AND B.FSUBID = C.FSUBID GROUP BY A.FNAME
------------------------------------------------------------------------
SELECT A.FNAME AS 姓名,
英語 = SUM(DECODE(B.FSUBNAME,’ 英語’,C.FSORE)),
數學 = SUM(DECODE(B.FSUBNAME,’ 數學’,C.FSORE)),
語文 = SUM(DECODE(B.FSUBNAME,’ 語文’,C.FSORE)),
歷史 = SUM(DECODE(B.FSUBNAME,’ 歷史’,C.FSORE)),
FROM STUDENT A, SUBJECT B, SCORE C
WHERE A.FID = C.FSTDID AND B.FSUBID = C.FSUBID GROUP BY A.FNAME
說明 這個案例主要是運用CASE與DECODE,當然也涉及GROUP BY的用法。
IDOC
RETURN
END
DECLARE @DOC VARCHAR(7999)
SELECT @DOC=
''<ROOT>
<DATASET>
<BOOKS>
<TITLE>Delphi</TITLE>
<AUTHOR>ABC</AUTHOR>
<PRICE>38.00</PRICE>
</BOOKS>
<BOOKS>
<TITLE>MIDAS</TITLE>
<AUTHOR>DEF</AUTHOR>
<PRICE>26.00</PRICE>
</BOOKS>
</DATASET>
</ROOT>''
EXEC UP_XML_TEST @DOC
--SELECT * FROM DBO.UF_XML_TEST(@DOC)
說明 用過程可以方便地對XML進行操作,但編寫成FUNCTION時就報錯,大概MS的函數內部不充許執行OPENXML等這類行集函數。另一個重要的問題是,SQL的這種語法竟然不支持漢字字串,真是要命。
38、使用DBMS_REPAIR檢測與修復破損的BLOCK?
ADMIN_TABLES 提供管理函數修復或孤立關鍵表,包含創建、淨化與刪除函數。
CHECK_OBJECT 檢測並報告表或索引的破損塊。
DUMP_ORPHAN_KEYS 導出破損塊的數據
FIX_CORRUPT_BLOCKS 在CHECK_OBJECT檢測出的破損塊上做標記
REBUILD_FREELISTS 重建對象的FREELISTS
SKIP_CORRUPT_BLOCKS 設置在表或索引掃描時是否不掃描被做了破損標記的塊。
SEGMENT_FIX_STATUS 整理BITMAP實體上的破損標志
上表列舉了DBMS_REPAIR包所有的過程,下邊將對這些過程要引入的參數的枚舉值進行
說明,這引些參數將在過程應用中起決定作用。
object_type TABLE_OBJECT, INDEX_OBJECT, CLUSTER_OBJECT
action CREATE_ACTION, DROP_ACTION, PURGE_ACTION
table_type REPAIR_TABLE, ORPHAN_TABLE
flags SKIP_FLAG, NOSKIP_FLAG
SQL> EXEC DBMS_REPAIR.ADMIN_TABLES(''SCOTT.EMP'',DBMS_REPAIR.REPAIR_TABLE,-
DBMS_REPAIR.CREATE_ACTION,''USERS'');
ORA-24129: 表名 SCOTT.EMP 沒有以前綴 REPAIR_ 開始
SQL> EXEC DBMS_REPAIR.ADMIN_TABLES(''REPAIR_EMP'',DBMS_REPAIR.REPAIR_TABLE,-
DBMS_REPAIR.CREATE_ACTION,''USERS'');
SQL> SELECT OBJECT_NAME FROM REPAIR_EMP;
SQL> EXEC DBMS_REPAIR.ADMIN_TABLES(''ORPHAN_EMP'',DBMS_REPAIR.ORPHAN_TABLE,-
DBMS_REPAIR.CREATE_ACTION,''USERS'');
SQL> SELECT TABLE_NAME FROM ORPHAN_EMP;
ADMIN_TABLES過程可以創建DBMS_REPAIR包的使用中需要的一些輔助表。
SQL> DECLARE
M INTEGER;
BEGIN
DBMS_REPAIR.CHECK_OBJECT(SCHEMA_NAME=>''SCOTT'',
OBJECT_NAME=>''EMP'',
> /
創建JOB
SQL> VARIABLE JOB1 NUMBER;
SQL>
SQL> BEGIN
DBMS_JOB.SUBMIT(:JOB1,''UP_TEST;'',SYSDATE,''SYSDATE+1/(24*60)'');
--每天1440分鐘,即一分鐘運行TEST過程一次
END;
/
運行JOB
SQL> BEGIN
DBMS_JOB.RUN(:JOB1);
END;
/
查看結果
SQL> SELECT TO_CHAR(DT,''YYYY/MM/DD HH24:MI:SS'') 時間 FROM A_JOB;
時間
-------------------
2001/01/07 23:51:21
2001/01/07 23:52:22
2001/01/07 23:53:24
刪除JOB
SQL> BEGIN
2 DBMS_JOB.REMOVE(:JOB1);
3 END;
4 /
說明:JOB1是BIND VARIABLE(綁定變量),相當於一個常局變量,在當前會話的生命期內可以引用,如果我們要刪除一個JOB,通常是從USER_JOBS字典中找到JOB的ID。
SQL> SELECT JOB FROM USER_JOBS;
SQL>EXEC DBMS_JOB.REMOVE(上一句查出來的JOB號);
41、關於DBMS_SQL包的使用方法?
DBMS_SQL包是動態執行SQL語句的一個包,它使用方法比EXECUTE IMMEDIATE復雜,但功能更強大一些,最主要的是它執行的SQL可以超出64K的限制,DBMSSQL.SQL是該包的SQL源程序(RDBMS目錄內)。
DECLARE
T_C1_TNAME USER_TABLES.TABLE_NAME%TYPE;
T_COMMAND VARCHAR2(200);
T_CID INTEGER;
T_TOTAL_RECORDS NUMBER(10);
STAT INTEGER;
ROW_COUNT INTEGER;
T_LIMIT INTEGER := 0;
--限制只取出記錄大於0的表的情況
CURSOR C1 IS SELECT TABLE_NAME FROM USER_TABLES ORDER BY TABLE_NAME;
--查出所有表的名字
BEGIN
T_LIMIT := 0;
OPEN C1;
LOOP
--取出一個表名
FETCH C1 INTO T_C1_TNAME;
--如果游標記錄取完,退出循環
EXIT WHEN C1%NOTFOUND;
T_COMMAND := ''SELECT COUNT(0) FROM ''||T_C1_TNAME;
T_CID := DBMS_SQL.OPEN_CURSOR;
--創建一個游標
DBMS_SQL.PARSE(T_CID,T_COMMAND,DBMS_SQL.NATIVE);
--向服務器發出一個語句並檢查這個語句的語法和語義錯誤
DBMS_SQL.DEFINE_COLUMN(T_CID,1,T_TOTAL_RECORDS);
--定義將從FETCHROWS()函數接收數據的變量的
STAT := DBMS_SQL.EXECUTE(T_CID);
--執行此語句,必須跟著FETCH_ROWS函數並為單個行檢索數據
ROW_COUNT := DBMS_SQL.FETCH_ROWS(T_CID);
--取回一行數據放入局部緩沖區
DBMS_SQL.COLUMN_VALUE(T_CID,1,T_TOTAL_RECORDS);
--返回調用FETCHROWS()取回的值,值存儲在T_TOTAL_RECORDS中
IF T_TOTAL_RECORDS > T_LIMIT THEN
DBMS_OUTPUT.PUT_LINE(RPAD(T_C1_TNAME,55,'' '')||
TO_CHAR(T_TOTAL_RECORDS,''99999999'')||'' RECORD(S)'');
END IF;
DBMS_SQL.CLOSE_CURSOR(T_CID);
END LOOP;
CLOSE C1;
END;
42、SQL與Oracle取隨機數的方法,本例要求從65到97之間的隨機數?
SELECT 65+FLOOR(RAND()*26)
-------------------------------------------
SELECT FLOOR(DBMS_RANDOM.VALUE(65,97)) FROM DUAL
43、SQL與Oracle取系統時間的方法
SELECT GETDATE()
-------------------------------------------
SELECT TO_CHAR(SYSDATE,
''YYYY-MM-DD HH24:MM:SS'') FROM DUAL
/>46、SQL與Oracle如何延時執行程序?
WAITFOR DELAY ‘00:01:00’ --延時一分鐘
WAITFOR TIME ’12:00:00’ --定時到12點整
------------------------------------------------
SQL>EXEC DBMS_LOCK.SLEEP(1)
說明:DBMS_LOCK.SLEEP延時一分鐘與SQL第一條語法作用相當。
47、SQL與Oracle如何返回服務器的IP地址?
CREATE PROCEDURE GETIP
AS
BEGIN
CREATE TABLE M(DEMO VARCHAR(7999))
DECLARE @SQL VARCHAR(99)
SELECT @SQL=''XP_CMDSHELL ''+''''''IPCONFIG''''''
INSERT INTO M EXEC(@SQL)
DECLARE @S VARCHAR(99),@IP VARCHAR(24),@P INT,@L INT
SELECT @S=RTRIM(LTRIM(DEMO)) FROM M WHERE DEMO LIKE ''%IP ADDRESS%''
SELECT @L=LEN(@S),@P=CHARINDEX('':'',@S,1)
SELECT @IP=RTRIM(LTRIM(RIGHT(@S,@L-@P)))
SELECT @IP
DROP TABLE M
END
EXEC GETIP
------------------------------------------------------------
SELECT SYS_CONTEXT(''USERENV'',''IP_ADDRESS'') FROM DUAL;
EXEC DBMS_OUTPUT.PUT_LINE(UTL_INADDR.GET_HOST_ADDRESS);
說明 SYS_CONTEXT求客戶端IP地址,一般在觸發器中使用
48、SQL與Oracle中對象是如何重命名的?
EXEC SP_RENAME ‘舊表名’,’新表名’
EXEC SP_RENAME ‘表名.字段名’,’新字段名’
EXEC SP_RENAMEDB ‘舊數據庫名’,’新數據庫名’
------------------------------------------------------------
RENAME 舊表名 TO 新表名
數據庫重命名可以用NID(從9I開始),字段重命名暫缺。
49、Oracle9I中INSERT 的新語法,源表的結構與數據示例如下:
SQL>SELECT * FROM sales_input_table;
PRODUCT_ID CUSTOMER_ID WEEKLY_ST SALES_SUN SALES_MON SALES_TUE SALES_WED SALES_THU SALES_FRI SALES_SAT
---------- ----------- --------- ---------- ---------- ---------- -------------------- ---------- ----------
111 222 01-OCT-00 100 200 300 400 500 600 700
222 333 08-OCT-00 200 300 400 500 600 700 800
333 444 15-OCT-00 300 400 500 600 700 800 900
sales_input_table表存儲了商品每周的銷售明細,將它轉成如下所示?
PROD_ID CUST_ID TIME_ID C PROMO_ID QUANTITY_SOLD AMOUNT COST
---------- ---------- --------- - ---------- ------------- ---------- ----------
111 222 01-OCT-00 100
111 222 02-OCT-00 200
111 222 03-OCT-00 300
111 222 04-OCT-00 400
111 222 05-OCT-00 500
111 222 06-OCT-00 600
111 222 07-OCT-00 700
222 333 08-OCT-00 200
222 333 09-OCT-00
300
222 333 10-OCT-00 400
222 333 11-OCT-00 500
222 333 12-OCT-00 600
222 333 13-OCT-00 700
222 333 14-OCT-00 800
333 444 15-OCT-00 300
333 444 16-OCT-00 400
333 444 17-OCT-00 500
333 444 18-OCT-00 600
333 444 19-OCT-00 700
333 444 20-OCT-00 800
333 444 21-OCT-00 900
請看下邊的這組SQL語句,成功而方便地解決這個問題
SQL> INSERT ALL
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date, sales_sun)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+1, sales_mon)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+2, sales_tue)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+3, sales_wed)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+4, sales_thu)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+5, sales_fri)
INTO sales (prod_id, cust_id, time_id, amount)
VALUES (product_id, customer_id, weekly_start_date+6, sales_sat)
SELECT product_id, customer_id, weekly_start_date, sales_sun,
sales_mon, sales_tue, sales_wed, sales_thu, sales_fri, sales_sat
FROM sales_input_table;
剛才看了INSERT ALL的用法,現在再看看INSERT ALL與WHEN的用法:
CREATE TABLE small_orders
(order_id NUMBER(12) NOT NULL,
customer_id NUMBER(6) NOT NULL,
order_total NUMBER(8,2),
sales_rep_id NUMBER(6) );
CREATE TABLE medium_orders AS SELECT * FROM small_orders;
CREATE TABLE large_orders AS SELECT * FROM small_orders;
CREATE TABLE special_orders
(order_id NUMBER(12) NOT NULL,
cid)
51、Oracle9i中MERGE的用法,若目錄表中有匹配數據就更新,否則就添加新數據
MERGE INTO TABLE_NAME AS TABLE_ALIAS
USING (TABLE|VIEW|SUB_QUERY) AS ALIAS
ON (JOIN CONDITION)
WHEN MATCHED THEN UPDATE SET COL1 = COL_VAL1,COL2 = COL2_VAL
WHEN NOT MATCHED THEN INSERT (COLUMN_LIST) VALUES (COLUMN_VALUES);
用SCOTT/TIGER登錄測試
SQL> SELECT * FROM DEPT;
SQL>CREATE TABLE BBB
AS
SELECT * FROM DEPT WHERE DEPTNO IN (10,20);
SQL>MERGE INTO BBB
USING DEPT ON (DEPT.DEPTNO=BBB.DEPTNO)
WHEN MATCHED THEN UPDATE SET DNAME=DEPT.DNAME,LOC=DEPT.LOC
WHEN NOT MATCHED THEN INSERT (DEPTNO,DNAME,LOC) VALUES (DEPT.DEPTNO,DEPT.DNAME,DEPT.LOC);
52、Oracle系統觸發器的類型與使用介紹(SQL沒有系統觸發器)
系統級觸發器事件:
AFTER SERVERERROR 服務器錯誤觸發
AFTER LOGON 登錄後觸發
BEFORE LOGOFF 退出登錄前觸發
AFTER STARTUP 啟動數據庫後觸發
AFTER SUSPEND 數據庫掛起後觸發(9i新增)
BEFORE SHUTDOWN 數據庫關閉前觸發
猜想,即然有SUSPEND事件,應該就喚醒事件,不知如何寫?創建系統觸發器時需要指定作用范圍:ON DATABASE或ON SCHEMA。
CREATE OR REPLACE TRIGGER TRIGGER_NAME
TIMING
DATABASE_EVENT1 or DATABSE_EVENT2 ON DATABASE|SCHEMA
TRIGGER BODY
53、DBMS_SPACE包的使用方法?(在RDBMS\ADMIN\DBMSSPC.SQL文件中)
SQL>DESC DBMS_SPACE可以看到DBMS_SPACE包提供了三個過程:
PROCEDURE FREE_BLOCKS 對象未使用的塊計算
PROCEDURE SPACE_USAGE 對象使用的空間計算
PROCEDURE UNUSED_SPACE 對象未使用空間計算
以FREE_BLOCKS過程為例:
SQL>SELECT FREELISTS,FREELIST_GROUPS,NUM_FREELIST_BLOCKS FROM DBA_TABLES
INPUT WHERE TABLE_NAME=''EMP'';
SQL> DECLARE
FBLKS NUMBER;
BEGIN
DBMS_SPACE.FREE_BLOCKS(''SCOTT'',''EMP'',''TABLE'',0,FBLKS);
DBMS_OUTPUT.PUT_LINE(FBLKS);
END;
說明:0是從DBA_TABLES字典表中求得的EMP表的FREELIST_GROUP_ID,FBLKS就是求得的EMP表的未使用的BLOCK NUMBER。
54、SQL Server 2000一個表裡有一個ID字段和若干INT字段,能不能用一個SQL語句對這些INT求和。表結構如下:ID INT1 INT2 INT3 INT4(C,I,I,I,I)
如這樣的表
A 1 2 3 4
B 2 3 4 6
C 5 7 10 11
最後的出的是
A 1 2 3 4 10
B 2 3 4 6 15
C 5 7 10 11 33
總數 8 12 17 21 58
CREATE TABLE A_SUM(ID VARCHAR(20),I1 INT,I2 INT)
INSERT INTO A_SUM VALUES(''01'',2,3)
INSERT INTO A_SUM VALUES(''02'',3,4)
SELECT ID,I1,I2,I1+I2 TOTAL FROM A_SUM
UNION
SELECT ''匯總'',SUM(I1), SUM(I2),SUM(I1)+SUM(I2) FROM A_SUM
55、表A只有一列LANE。現在A中有如下行表示一些城市對 ,數據如下:
LANE
-------------------------------------------
上海-北京
北京-上海
上海-南京
南京-上海
廣州-長沙-武漢
武漢-長沙-廣州
北京-東京
我希望通過一條SQL查詢,能將其中“重復”的城市對過濾掉,即形成如下結果。至於出現的是“上海-北京”還是“北京-上海”我倒不在意。
LANE
------------------------------------
-------
北京-上海
上海-南京
武漢-長沙-廣州
北京-東京
網友NYFOR的解決方法如下:
CREATE TABLE A(LANE VARCHAR2(255));
INSERT INTO A VALUES(''上海-北京'');
INSERT INTO A VALUES(''北京-上海'');
INSERT INTO A VALUES(''上海-南京'');
INSERT INTO A VALUES(''南京-上海'');
INSERT INTO A VALUE