日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL 与 ORACLE 的比较

發布時間:2024/7/5 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL 与 ORACLE 的比较 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近參加了一個ORACLE的培訓,ORACLE與平日慣用的SQL SERVER果然有很大不同,在網上搜索了一下轉了這篇比較SQL與ORACLE的帖子,總體上感覺SQL SERVER使用更加便捷,人性化,在網上的資料支持很豐富ORACLE更加專家一些,性能可能也強一些,很多東西可以由管理員來配置,管理員手段更加豐富


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))
PARTITION BY LIST(ID)(
PARTIION P1 VALUES(‘01’,’03’,’05’) PARTITON P2 VALUES(‘02’,’04’))
012、SQL與ORACLE的存儲過程
SQL的存儲過程可以很方便地返回結果集,ORACLE的存儲過程只有通過游標類型返回結果集,這種結果集ADO不可識別,如果想使用ORACLE存儲過程的結果集,只有使用ODAC開發包SQL的過程參數如果是字符必須指定參數長度,ORACLE的過程則不充許指定字符參數的長度。
CREATE PROCEDURE UP_001(@ID INT) AS
BEGIN
SELECT ID ,SUM(QTY) FROM A_TEST WHERE ID=@ID GROUP BY @ID
END
------------------------------------------------------------
CREATE OR REPLACE PACKAGE UP_002 AS
TYPE MYCURSOR IS REF CURSOR;
FUNCTION GETRECORD RETURN MYCURSOR;
END;
CEEATE OR REPLACE PACKAGE BODY UP_002 AS
FUNCTION GETRECORD RETURN MYCURSOR AS
MC MYCURSOR;
SL VARCHAR2(999);
BEGIN
OPEN MC FOR SELECT * FROM A001;
RETURN MC;
END;
END;
ORACLE的存儲函數返回結果這么艱難,但SQL的觸發器竟然也充許返回結果集就令人費解啦,觸發器的調試比較麻煩,在SQL實際開發中,一般都將觸發器要執行的代碼放到過程中進行調試,在查詢分析器中可以對過程進行設斷點調試。
013、SQL與ORACLE的觸發器
觸發器的事務是引起觸發動作事務的延續,在SQL的觸發器中是可以無BEGIN TRAN而可以直接COMMIT TRAN的。SQL的觸發器是表級觸發器,DML影響一行或無數行觸發動作只觸發一次,ORACLE分表級觸發器與行級觸發器,觸發的粒度更細膩一些, SQL在處理多行時就必須使用CURSOR啦。ORACLE使用INSERTING、DELTING、UPDATING判斷執行了什么DML操作,SQL 只有判斷INSERTED、DELETED的記錄數來判斷執行了什么操作,只有INSERTED映象表記錄數大于0表示INSERT,只有DELETED 映象表記錄數大于0表示DELETE,若兩個表記錄數都大于0表示UPDATE。
用SQL的觸發器實現級聯添加、級聯刪除、級聯更新
CREATE TABLE A1(ID INT,NAME VARCHAR(20))
CREATE TABLE A2(ID INT,NAME VARCHAR(20))
CREATE TRIGGER TRI_A1_INS ON A1
FOR INSERT , DELETE , UPDATE AS BEGIN
DECLARE @I INT,@D INT,@ID INT
SELECT @I=COUNT(*) FROM INSERTED
SELECT @D=COUNT(*) FROM DELETED
--IF (@I>0 AND @D>0) 執行更新,由于用到游標,故略去
IF @I>0
INSERT INTO A2 SELECT * FROM INSERTED
IF @D>0
DELETE FROM A2 WHERE ID=@ID
END
----------------------------------------------------------------------
用ORACLE的觸發器實現級聯添加、級聯刪除、級聯更新
CREATE OR REPLACE TRI_A1_INS
AFTER INSERT OR DELETE OR UPDATE ON A1
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO A2 SELECT * FROM :NEW;
END IF;
IF DELETING THEN
DELETE FROM A2 WHERE ID = :OLD.ID ;
END IF;
IF UPDATING THEN
UPATE A2 SET ID = :NEW.ID , NAME = :NEW.NAME WHERE ID = :OLD.ID ;
END IF;
END
014、SQL與ORACLE的游標
SQL的游標用@@FETCH_STATUS判斷是否還有數據,ORACLE的游標用%FOUND、%NOTFOUND來判斷游標是否結束,游標分服務端 游標與客戶端游標,在存儲過程、函數、觸發器中聲明的游標為服務端游標,其它處聲明的游標為客戶端游標,游標需要使用較多的內存,但它比臨時表的性能要優 一些,因為臨時表占用的是DISK I/O,DISK I/O應該比服務器的內存要更珍貴一些吧。
015、SQL與ORACLE的重復記錄刪除
好的數據庫設計重復記錄是不存在的,如果有重復記錄如何刪除呢?SQL可以使用SET ROWCOUNT N設置客戶端緩沖區的記錄來刪除,ORACLE可以使用ROWID來進行,都必須進行一些簡單的編程,SQL可以做用過程,更通用一些,ORACLE如果 想做得通過不太容易,字段小些會更方便處理一些。
DECLARE @M INT
SELECT @M=COUNT(*) FROM A_TEST WHERE ID=X
SELECT @M=@M-1
SET ROWCOUNT @M --限制客戶端緩沖區的記錄數
DELETE FROM A_TEST WHERE ID=X
SET ROWCOUNT 0 --取消限制
說明 刪除某條記錄的重復值,如果想清除表的所有重值要使用游標,取得所有的X
---------------------------------------------------------------------
DELETE FROM A_TEST A WHERE ROWID!=(SELECT MAX(ROWID) FROM A_TEST B
WHERE A.ID=B.ID AND A.NAME=B.NAME)
說明 當數據量較大時,這種方法將會使用系統大量的資源
016 SQL與ORACLE的對象加密
SQL與ORACLE的某些對象如過程、視圖、函數、觸發器可能涉及商業,開發商通常希望對這些對象進行加密,SQL的加密方法在創建時帶上WITH ENCRYPTION,ORACLE的對象加密明顯復雜一些,要使用WRAP工具,在ORACLE的BIN目錄內。
017 SQL與ORACLE的表生成SQL語句
SQL與ORACLE的表如何才導成SQL語句呢?如果一定要編程實現,SQL需要將其它數據類型的字段轉換成VARCHAR類型,ORACLE則可以隱式進行數據類型轉換。
CREATE TABLE A_SQL(ID INT,NAME VARCHAR(20)) –假如有兩萬記錄
SELECT ‘INSERT INTO A_SQL VALUES(‘+CAST(ID
AS VARCHAR(20))+’,’’’+NAME+’’’)’ FROM A_SQL
----------------------------------------------------------------
SELECT ‘INSERT INTO A_SQL VALUES(‘||ID||’,’||’’’||NAME||’’’||’)’
FROM A_SQL
說明 SQL的字符串連接用+號,ORACLE字符串連接用||,單引號可以做轉義符。
018、SQL與ORACLE的動態SQL
SQL與ORACLE都支持動態SQL語句,SQL用EXEC()執行的動態SQL語句,ORACLE用EXECUTE IMMEDIATE執行動態SQL。動態SQL的效率要比非動態SQL性能差,但使用起來非常靈活,可以根據不同條件執行不同的任務。
DECLARE @SQL VARCHAR(99)
SELECT @SQL=’declare @m int select @m=count(*) from sysobjects select @m’
EXEC(@SQL)
--------------------------------------------
DECLARE
S VARCHAR2(99);
BEGIN
S:='SELECT COUNT(*) FROM '||' USER_TABLES';
EXECUTE IMMEDIATE S;
END;
19、返回記錄集中前N條記錄的語法?
SQL只有使用TOP,ORACLE可以使用ROWNUM
SELECT TOP N * FROM 記錄集(表,視圖,子查詢)
---------------------------------------------
SELECT * FROM 記錄集 WHERE ROWNUM<=N
20 如何返回記錄集中相臨兩記錄之間某字段的差值?
CREATE TABLE A001(ID INT,QTY INT)
INSERT INTO A001 VALUES(1,20)
INSERT INTO A001 VALUES(4,10)
SELECT IDENTITY(INT,1,1) CODE,QTY INTO #X FROM A001
SELECT B.QTY-A.QTY FROM #X A,#X B WHERE A.CODE=B.CODE-1
DROP TABLE #X
--------------------------------------------------------
CREATE TABLE A002(ID INT)
INSERT INTO A002 VALUES(1)
INSERT INTO A002 VALUES(9)
WITH A AS (SELECT ROWNUM RN,ID FROM A002)
SELECT A2.ID-A1.ID FROM A A2,A A1 WHERE A2.RN=A1.RN-1
說明 雖然語法大不相同,但最大的特點是兩者都使用了自連接技術。
21 如何返回任意某個范圍之間的記錄集?
CREATE TABLE A03(ID INT)
DECLARE @I INT
SELECT @I=1
WHILE @I<1000 BEGIN
INSERT INTO A03 VALUES(@I)
SELECT @I=@I+1
END
--前部分是創建環境,后一部分是實現方法,比較牽強
SELECT IDENTITY(INT,1,1) CODE,ID INTO #X FROM A03
SELECT ID FROM #X WHERE CODE BETWEEN 10 AND 20
DROP TABLE #X
------------------------------------------------------
BEGIN
FOR I IN 1..999 LOOP
INSERT INTO A03 VALUES(I);
END LOOP;
END;

SELECT * FROM A03 WHERE ROWNUM<20
MINUS
SELECT * FROM A03 WHERE ROWNUM<10;
說明 在數據提取方面,ORACLE有ROWID,ROWNUM使之有相當強的優勢,SQL只有使用函數IDENTITY來構建一個臨時表,這樣來說還不好使用 CURSOR來性能會好一些。通過這個例子,大家還可以看出SQL與ORACLE的程序結構,ORACLE更嚴謹、人性化一些。
22、表A04中的含有A、B、C、D四個字段,當按A字段分組后,如果D等1,則只統計B的值,如果D等0,則只統計C的值。
CREATE TABLE A04(A VARCHAR(20),B INT,C INT,D INT)
INSERT INTO A04 VALUES('01',20,7,'0')
INSERT INTO A04 VALUES('01',10,8,'1')
INSERT INTO A04 VALUES('02',20,7,'1')
INSERT INTO A04 VALUES('02',10,8,'0')
SELECT A,SUM(CASE D WHEN 1 THEN B WHEN 0 THEN C END) FROM A04 GROUP BY A
---------------------------------------------------------------
SELECT A,SUM(DECODE(D,1,B,0,C)) FROM A04 GROUP BY A
說明 ORACLE 9I可以使用CASE語句來實現這種操作,但也可以用DECODE來作統計,使用CASE比DECODE提供了更為強大的功能,但DECODE的語法顯然比CASE WHEN THEN END要簡潔得多。
23、如何刪除數據庫所有表?(ORACLE則是刪除模式所有表)
DECLARE @SQL VARCHAR(99),@TBL VARCHAR(30),@FK VARCHAR(30)
DECLARE CUR_FK CURSOR LOCAL FOR
SELECT OBJECT_NAME(CONSTID),OBJECT_NAME(FKEYID) FROM SYSREFERENCES
--刪除所有外鍵
OPEN CUR_FK
FETCH CUR_FK INTO @FK,@TBL
WHILE @@FETCH_STATUS =0
BEGIN
SELECT @SQL='ALTER TABLE '+@TBL+' DROP CONSTRAINT '+@FK
EXEC(@SQL)
--SELECT @SQL='DROP TABLE '+@TBL
FETCH CUR_FK INTO @FK,@TBL
END
CLOSE CUR_FK
DECLARE CUR_FKS CURSOR LOCAL FOR
SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U'
OPEN CUR_FKS
FETCH CUR_FKS INTO @TBL
WHILE @@FETCH_STATUS =0
BEGIN
SELECT @SQL='DROP TABLE ['+@TBL+']'
EXEC(@SQL)
FETCH CUR_FKS INTO @TBL
END
CLOSE CUR_FKS
----------------------------------------------------------------
DECLARE
S VARCHAR2(99);
CURSOR CUR_F IS SELECT CONSTRAINT_NAME,TABLE_NAME FROM USER_CONSTRAINTS
WHERE CONSTRAINT_TYPE='R';
CURSOR CUR_T IS SELECT TABLE_NAME FROM USER_TABLES;
BEGIN
FOR V IN CUR_F LOOP
S:='ALTER TABLE '||V.TABLE_NAME||' DROP CONSTRAINT '||V.CONSTRAINT_NAME;
EXECUTE IMMEDIATE S;
END LOOP;
FOR T IN CUR_T LOOP
S:='DROP TABLE '||T.TABLE_NAME;
EXECUTE IMMEDIATE S;
END LOOP;
END;
說明 SQL刪除數據庫時,用到了兩個系統表:SYSREFERENCES、SYSOBJECTS,前一個可以獲得所有外鍵鍵信息,后者可以獲得所有表的信息,在刪除表時還在表名上加了一對中括號,即使用表名含有空格鍵或其它特殊這符也可以順利刪除。
在ORACLE中,要刪除模式的所有表,方法和SQL差不多,需要用到的數據字典也有兩個:USER_CONSTRAINTS、USER_TABLES; USER_CONSTRAINTS中CONSTRAINT_TYPE值等于R表示是外鍵,同樣也要用到CURSOR與動態SQL,這里提醒一下大家, FOR … LOOP內的變量變量是FOR … LOOP聲明的,可以ORACLE的程序結構比SQL簡潔。
24、如何統計數據庫所有用戶表的記錄數(ORACLE統計模式內所有表的記錄數)?
CREATE TABLE #TMP (QTY INT)
CREATE TABLE #TMP1 (TBL VARCHAR(30),QTY INT)
DECLARE @SQL VARCHAR(99),@TBL VARCHAR(30),@QTY INT
DECLARE CUR_FKS CURSOR LOCAL FOR
SELECT NAME FROM SYSOBJECTS WHERE XTYPE='U'
OPEN CUR_FKS
FETCH CUR_FKS INTO @TBL
WHILE @@FETCH_STATUS =0
BEGIN
SELECT @SQL='SELECT COUNT(*) FROM '+@TBL
INSERT INTO #TMP EXEC(@SQL)
SELECT @QTY=QTY FROM #TMP
INSERT INTO #TMP1 VALUES(@TBL,@QTY)
DELETE FROM #TMP
FETCH CUR_FKS INTO @TBL
END
CLOSE CUR_FKS
SELECT * FROM #TMP1
---------------------------------------------------------------
DESC DBMS_UTILITY
EXECUTE DBMS_UTILITY.ANALYZE_SCHEMA('SCOTT','COMPUTE');
SELECT TABLE_NAME,NUM_ROWS FROM USER_TABLES;
說明 SQL的EXEC功能可謂十分強大,竟然可以和INSERT INTO合用,將結果集存入一個表中,MS可真牛。ORACLE就只好用個偷懶的方法,首先將要統計的模式進行統計分析,在數據字典中就記載了每個表的行數,ORACLE很簡單吧。
25、SQL與ORACLE快速建表的方法?
SELECT * INTO 新表名稱 FROM 子查詢|表名
-----------------------------------------
CREATE TABLE 新表名稱 AS 子查詢
說明 快速建表可以有效地消除碎片,速度極快。
26、如何實現有一組有規則的編號(如200305310001…200305310999)?
DECLARE @I INT,@C VARCHAR(20)
SELECT @I=1
WHILE @I<1000 BEGIN
SELECT @C=CASE WHEN @I<10 THEN '000'+CAST(@I AS CHAR(1))
WHEN @I BETWEEN 10 AND 99 THEN '00'+CAST(@I AS CHAR(2))
WHEN @I BETWEEN 100 AND 999 THEN '0'+CAST(@I AS CHAR(3))
END
SELECT @C=CONVERT(VARCHAR(20),GETDATE(),112)+@C
SELECT @C --在查詢分析器中輸出
SELECT @I=@I+1
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的用法。
29、有兩個表,用一條SQL語句算出商品A,B目前還剩多少?表結構如下:
商品名稱mc 商品總量sl 表一(AAA)
A 100
B 120
商品名稱mc 出庫數量sl 表二(BBB)
A 10
A 20
B 10
B 20
SELECT TA.商品名稱,A-B AS 剩余數量 FROM
(SELECT 商品名稱,SUM(商品總量) AS A FROM AAA GROUP BY 商品名稱)TA,
(SELECT 商品名稱,SUM(出庫數量) AS B FROM BBB GROUP BY 商品名稱)TB
WHERE TA.商品名稱=TB.商品名稱
----------------------------------------------------------
SELECT 商品名稱,SUM(商品總量)剩余數量 FROM
(SELECT * FROM AAA
UNION ALL
SELECT 商品名稱,-出庫數量 FROM BBB)A GROUP BY 商品名稱
30、如何將A表的某個字段更新到表B的某個字段?
UPDATE A SET QTY=B.QTY FROM B WHERE A.CODE=B.CODE
---------------------------------------------------
UPDATE A SET QTY=(SELECT QTY FROM B WHERE B.CODE=A.CODE)
說明 這兩道題在語法上SQL與ORACLE沒有發別,只不過是兩種思路而已。
31、有一個商品銷售表,記載了某月商品的銷售數量,現在要為所有商品排名次,放到一個單獨的字段中,就是說達到右邊顯示的效果,如何作?
BU1032 5 NULL BU1032 5 2
PS2091 3 NULL PS2092 3 3
PC8888 50 NULL PC8888 50 1
UPDATE X SET ORD=(SELECT COUNT(*)+1 FROM X B WHERE B.QTY>X.QTY)
----------------------------------------------------------------
SELECT CODE,QTY,RANK() OVER (ORDER BY QTY) ORD FROM A_TEST
說明 SQL中的排序是通過UPDATE更新,然后再顯示出來,而ORACLE使用了RANK OVER函數,直接將數據集顯示出來,而且RANK OVER函數還可以通過PARTITION BY對分組中的數據進行排序。
32、SQL與ORACLE的文件結構
SQL文件被格式化為8K為單位的頁,每8個相鄰的頁稱為盤區(64K),若該盤區分配給一個對象,稱為一致盤區,若分配給多個對象等為混合盤區,SQL 有全局分配頁面、數據頁面、索引頁頁、BLOB頁面、TEXT頁面。ORACLE的文件最小邏輯單位是由INIT.ORA中的BLOCK_SIZE的值決 定的,可以取2K、4K、6K、8K、16K、32K等,ORACLE的盤區是由一些塊組成的,ORACLE的段是由盤區組成的,ORACLE有數據段、 索引段、回退段(UNDO段)、臨時段、CLOB/BLOB段、CLUSTER段等。
33、SQL與ORACLE如何取得一個全局唯一標識標(GUID)
SELECT NEWID()
----------------------------------
SELECT SYS_GUID() FROM DUAL
34、本人有一張表單, 要求統計COL1~COL6中不等于2的列的個數,數據如下:
————————————————————————————————
ROW_ID | COL1 | COL2 | COL3 | COL4 | COL5 | COL6 |
1 | 2 | 1 | 1 | 2 | 3 | 2 |
2 | 1 | 1 | 2 | 2 | 2 | 2 |
3 | 2 | 3 | 2 | 2 | 1 | 2 |
4 | 2 | 2 | 2 | 2 | 1 | 2 |
5 | 1 | 2 | 2 | 2 | 2 | 2 |
6 | 2 | 2 | 2 | 2 | 2 | 1 |
————————————————————————————————
要求結果如下:
—————————
ROW_ID | COUNT |
1 | 3 |
2 | 2 |
3 | 2 |
4 | 1 |
5 | 1 |
6 | 1 |
SELECT ROW_ID,(6-(CASE WHEN COL1=2 THEN COL1 / 2 ELSE 0 END)
-(CASE WHEN COL2=2 THEN COL2 / 2 ELSE 0 END)
-(CASE WHEN COL3=2 THEN COL3 / 2 ELSE 0 END)
-(CASE WHEN COL4=2 THEN COL4 / 2 ELSE 0 END)
-(CASE WHEN COL5=2 THEN COL5 / 2 ELSE 0 END)
-(CASE WHEN COL6=2 THEN COL6 / 2 ELSE 0 END))AS COUNT FROM TABLE_A
35、有一客戶表,數據如下:
客戶 日期 資金
F001 2003-03-05 123.00
F002 2003-03-04 1223.00
F002 2003-03-02 1123.00
F003 2003-03-05 1231.00
F003 2003-03-04 1232.00
要求選出每個客戶最新的哪條記錄 組成一個結果集,結果如下:
F001 2003-03-05 123.00
F002 2003-03-04 1223.00
F003 2003-03-05 1231.00
實現方法:
SELECT A.客戶, B.日期, A.資金 FROM 客戶資金表 A,
(SELECT 客戶, MAX(日期) 日期 FROM 客戶資金表 GROUP BY 客戶 ) B
WHERE A.客戶 = B.客戶 AND A.日期 = B.日期
36 現在看一個高難度的作業,后來解決辦法和本例不同,請看需求。
視圖1 CITYWATER_VIEW
行政區劃名稱 城市用水量(億M3) 。。。
北京市 15000 …
上海市 9000 …
天津市 5400 …
重慶市 9500 …



表2 CODE
區劃 代碼
北京市 100000
上海市 200000
天津市 300000
表3 CITYWATER
代碼 城市用水
100000 15000
200000 9000
300000 5400
表1 DICTIONARY
字段別名 字段全名
區劃 行政區劃名稱
代碼 行政區劃代碼
城市用水 城市用水量(億M3)

表1-2是數據庫public中的基表,表3是數據庫water中的基表;在數據庫water中創建視圖1,用T-SQL語句怎樣實現?把查詢結果的“字 段別名”修改為視圖中的“字段全名”,如果采用T-SQL中的常用修改列標題方式(SELECT column_name AS expression或者SELECT expression= column_name ),很煩,每個基表里的字段太多,并且基表有近200個,字段近3000個。
說明:其實現在要作的就是將表3中的“代碼“、“城市用水”替代成表1中的行政區劃代碼、城市用戶量(億M3)等。
CREATE VIEW V_GOD
AS SELECT A.[100000],B.[310000],B.[114011],B.[114111],B.[114421],B.[114311],B.[114321] FROM CODE A,FA01P B WHERE A.[200000]=B.[200000]
DECLARE CUR_COL CURSOR LOCAL FOR
SELECT NAME FROM SYSCOLUMNS WHERE ID=OBJECT_ID('V_GOD')
DECLARE @COL VARCHAR(20),@SQL VARCHAR(999),
@COL_TOTAL VARCHAR(8000),@ALIAS VARCHAR(99),
@SOURCE VARCHAR(8000)
OPEN CUR_COL
FETCH CUR_COL INTO @COL
WHILE @@FETCH_STATUS=0
BEGIN
SELECT @ALIAS=字段名 FROM DICTIONARY WHERE 段碼=@COL
IF @COL_TOTAL IS NULL
SELECT @COL_TOTAL=@ALIAS
ELSE
SELECT @COL_TOTAL=@COL_TOTAL+','+@ALIAS
FETCH CUR_COL INTO @COL
END
CLOSE CUR_COL
SELECT @SOURCE=RTRIM(TEXT) FROM SYSCOMMENTS WHERE ID=OBJECT_ID('V_GOD')
SELECT @SOURCE=RTRIM(SUBSTRING(@SOURCE,CHARINDEX('AS',@SOURCE),LEN(@SOURCE)))
SELECT @SOURCE='ALTER VIEW V_GOD('+@COL_TOTAL+') '+@SOURCE
EXEC(@SOURCE)
說明 由于該實例需要的表有兩個已沒有記錄,所以大家只有看看T-SQL的語法及動態SQL的編寫,ORACLE也類似。
37、如何用SQL操作一段XML文件?
CREATE PROCEDURE UP_XML_TEST(@DOC VARCHAR(7999))
AS
BEGIN
DECLARE @IDOC INT
EXEC SP_XML_PREPAREDOCUMENT @IDOC OUTPUT, @DOC
SELECT *
FROM OPENXML (@IDOC, '/ROOT/DATASET/BOOKS',2)
WITH(TITLE VARCHAR(32) 'TITLE',
AUTHOR VARCHAR(20) 'AUTHOR',
PRICE DECIMAL(9,2) 'PRICE')
EXEC SP_XML_REMOVEDOCUMENT @IDOC
END

CREATE FUNCTION UF_XML_TEST(@DOC VARCHAR(7999))
RETURNS @T TABLE(TITLE VARCHAR(32),
AUTHOR VARCHAR(20),
PRICE DECIMAL(9,2))
AS
BEGIN
DECLARE @IDOC INT
EXEC SP_XML_PREPAREDOCUMENT @IDOC OUTPUT, @DOC
INSERT INTO @T SELECT *
FROM OPENXML (@IDOC, '/ROOT/DATASET/BOOKS',2)
WITH(TITLE VARCHAR(32) 'TITLE',
AUTHOR VARCHAR(20) 'AUTHOR',
PRICE DECIMAL(9,2) 'PRICE')
EXEC SP_XML_REMOVEDOCUMENT @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)

轉載于:https://www.cnblogs.com/ioriwuhj/archive/2008/06/27/1231357.html

總結

以上是生活随笔為你收集整理的SQL 与 ORACLE 的比较的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。