1. 程式人生 > >Sybase IQ的使用心得(對比Oracle)

Sybase IQ的使用心得(對比Oracle)

現在專案組使用的資料庫是Sybase,之前都是用Oralce的,在熟悉Sybase時發現Sybase的資料還是很少的(尤其網上資料),摸索很長時間後才慢慢適應過來,閒餘之時,總結了下Sybase IQ的使用心得,由於之前用的的Oralce,所以有的差異也是和Oralce作的比較。
希望能幫到Sybase初學者。
==================================使用總結===========================================
1、字母大小寫比對不敏感,也就是在值比對判斷時大小寫字母都一樣;
2、等值,或<>判斷,系統預設對等式兩邊比對值去右邊空格再進行比較;

3、GROUP BY 可以根據SELECT欄位或表示式的別名來 彙總,在編寫時也儘量避免SELECT 語句的別名與FROM表中的欄位有重複,不然會出現莫名其妙的錯誤;
4、FROM後的子查詢 要定義別名才可使用;
5、儲存過程要返回IQ系統錯誤資訊 SQLCODE || ERRORMSG(*) :(兩者都為EXCEPTION後第一條SQL語句才有效果);
6、IQ中若採用 FULL JOIN 連線則不能使用 WHERE 條件,否則FULL JOIN將失效,要篩選條件則用子查詢先過濾記錄後再FULL JOIN;
7、建表時,欄位預設為非空;
8、UPDATE語句,如果與目標表關聯的表有多條,則不會報錯,而是隨機取一條更新(第一條);

9、RANK() OVER(PARTITION BY .. ORDER BY ..) 分組分析函式,相同的ORDER BY值,返回順序值一樣,且PARTITION BY 只支援一個欄位或一個欄位組(需多個欄位分組的則要用 || 拼為一個欄位(待確認,該問題以前碰過一次,再次驗證卻不存在這問題))
10、返回可讀的 全域性唯一字元:UUIDTOSTR(NEWID())
11、儲存過程隱式遊標語法:
FOR A AS B CURSOR FOR SELECT ... FROM ... 
DO
.... 過程語句
END FOR;
需要注意的時,這邊的A 和 B 在 過程語句中都不能引用,所以為避免過程語句其他欄位名與FOR SELECT 語句的欄位名稱重複,FOR SELECT 語句的欄位最好都定義別名區分

12、根據SELECT 語句建立[臨時]表的方法(ORACLE的CREATE TABLE)為 SELECT ..[*] INTO [#]table_name FROM ..; 其中如果在table_name加字首#,則為會話級臨時表,否則為實體表;
13、因Sybase為列儲存模式,在執行上INSERT語句會比UPDATE語句慢,尤其表資料越多INSERT效率就越慢;所以在ETL時建議多用UPDATE而不是INSERT
14、雖說Sybase為列儲存模式,每個欄位上都有預設索引,但對於經常的兩表的關聯鍵還是要建立索引否則會經常報QUERY_TEMP_SPACE_LIMIT不足的錯誤;
15、儲存過程中也可以顯示的執行DDL語句,這點與Oracle不同;
16、空字串''在Sybase中也是個字元而不是null值,這點要注意;
17、調整SESSION的臨時空間SET TEMPORARY OPTION QUERY_TEMP_SPACE_LIMIT = '150000'; 15000為大小,如寫0則沒限制大小
==================================常用函式===========================================
字串函式
1)ISNULL(EXP1,EXP2,EXP3,...) :返回第一個非空值,用法與COALESCE(exp1,exp2[,exp3...])相同
3)TRIM(exp) :去除兩邊空格
4)DATEFORMAT(date_exp,date_format) :日期型轉字元型;
5)STRING(exp):轉為字元型;
6)SUBSTRING(exp,int-exp1,[int-exp2]):擷取exp從int-exp1開始,擷取int-exp2個字元;
7)REPLACE(o-exp,search-exp,replace-exp):從o-exp搜尋search-exp,替換為replace-exp;
8)SPACE(int_exp):返回int個空格;
8)UPPER(exp):轉為大寫字母,等價於UCASE(exp);
8)LOWER(exp):轉為小寫字母,
8)CHARINDEX(exp1,exp2):返回exp2字串中exp1的位置!定位,exp1 查詢的字元,exp2 被查詢的字串;
8)DATALENGTH(CHAR_EXPR):在char_expr中返回字元的長度值,忽略尾空;
8)RIGHT(char_expr,int_expr):返回char_expr右邊的int_expr個字元;
8)LEFT(char_expr,int_expr):返回char_expr左邊的int_expr個字元;
8)REPLICATE(char_expr,int_expr):重複char_expr,int_expr次;
8)STUFF(expr1,start,length,expr2):用expr2代替epxr1中start起始長為length的字串;
8)REVERSE(char_expr):反寫char_expr中的文字;
8)LTRIM(char_expr):刪除頭空;
8)RTRIM(char_expr):刪除尾空;
8)STR(float_expr[,length[,decimal]]):進行數值型到字元型轉換;
8)PATINDEX("%pattern%",expression):返回指定樣式的開始位置,否則為0;
8)NULLIF(exp1,exp1):比較兩個表示式,如果相等則返回null值,否則返回exp1
8)NUMBER(*):返回序號,相當於ORACLE的rowid,但有區別;
其他函式
8)RANK() OVER(PARTITION BY .. ORDER BY ..) 分組分析函式,相同的ORDER BY值,返回順序值一樣,且PARTITION BY 只支援一個欄位或一個欄位組(需多個欄位分組的則要用 || 拼為一個欄位(待確認))
8)返回可讀的 全域性ID UUIDTOSTR(NEWID())
8)COL_LENGTH(tab_name,col_name):返回定義的列長度;相容性:IQ&ASE
8)LENGTH(exp):返回exp的長度;相容性:IQ
轉換函式
8)CONVERT(datetype,exp[,format-style]):字元轉日期型 或DATE(exp);相容性:IQ&ASE
format-style值  輸出:
112            yyyymmdd
120  yyyy-mm-dd hh:nn:ss
SELECT CONVERT(date,'20101231',112),CONVERT(varchar(10),getdate(),120) ; 
--結果 
                  2010-12-31                   2011-04-07
8)CAST(exp AS data-type):返回轉換為提供的資料型別的表示式的值; 相容性:IQ
日期函式
8)DAY(date_exp):返回日期天值,DAYS(date_exp,int):返回日期date_exp加int後的日期;MONTH與MONTHS、YEAR與YEARS同理;
8)DATE(exp):將表示式轉換為日期,並刪除任何小時、分鐘或秒;相容性:IQ
8)DATEPART(date-part,date-exp): 返回日期分量的對應值(整數);
8)GETDATE():返回系統時間;
8)DATENAME(datepart,date_expr):以字串形式返回date_expr指定部分的值,轉換成合適的名字;
8)DATEDIFF(datepart,date_expr1,date_expr2):返回date_expr2-date_expr1,通過指定的datepart度量;
8)DATEADD(date-part,num-exp,date-exp):返回按指定date-part分量加num-exp值後生成的date-exp值;相容性:IQ&ASE
date-part日期分量代表值:
縮寫  值
YY   0001-9999
QQ   1-4
MM   1-12
WK   1-54
DD   1-31
DY   1--366
DW   1-7(週日-週六)
HH   0-23
MI   0-59
SS   0-59
MS   0-999
數值函式
8)CEIL(num-exp):返回大於或等於指定表示式的最小整數;相容性:IQ&ASE;
8)FLOOR(numeric_expr):返回小於或等於指定值的最大整數;
8)ABS(num-exp):返回數值表示式的絕對值;相容性:IQ&ASE;
8)TRUNCNUM(1231.1251,2):擷取數值;不四捨五入;
8)ROUND(numeric_expr,int_expr):把數值表示式圓整到int_expr指定的精度;
8)RAND([int_expr]):返回0-1之間的隨機浮點數,可指定基值;
8)SIGN(int_expr):返回正+1,零0或負-1;
8)SQRT(float_expr):返回指定值的平方根; 
8)PI():返回常數3.1415926;
8)POWER(numeric_expr,power):返回numeric_expr的值給power的冪;
8)EXP(float_expr):給出指定值的指數值;

==================================常用DDL語句===========================================
Sybase中DDL語句不能修改欄位的資料型別,只能修改空與非空:
1.刪除列:
ALTER TABLE table_name DELETE column_name;
2.增加列:
ALTER TABLE table_name ADD (column_name DATA_TYPE [NOT] NULL);
3.修改列的空與非空:
ALTER TABLE table_name MODIFY column_name [NOT] NULL;
4.修改列名:
ALTER TABLE table_name RENAME old_column_name TO new_column_name;
5.快速建立臨時表:
SELECT * INTO [#]table_name FROM .....;
6、修改表名:
ALTER TABLE old_table_name RENAME new_table_name
7.增加主鍵約束:
ALTER TABLE tb_name ADD CONSTRAINT pk_name PRIMARY KEY(col_name,..)
8.刪除主鍵約束:
ALTER TABLE tb_name DROP CONSTRAINT pk_name;
9.建立自增長欄位,與Oracle的SEQUENCE類似:
CREATE TABLE TMP_001 (RES_ID INTEGER IDENTITY NOT NULL);
10.新增表註釋:
COMMENT ON TABLE table_name IS '....';
11.建立索引:

CREATE INDEX index_name ON table_name(column_name);

1.Oracle表名、欄位名不區分大小寫,Sybase嚴格區分 
2.Oracle中to_char()/to_date() ---Sybase的convert()
--Oracle:to_char(sysdate,'dd-mm-yyyy day'),to_date(string,format)
--Sybase:convert(char(15),日期,108),convert(datetime,string,108)
--末尾附 Sybase convert第三個引數介紹
3.Oracle中 substr() -- Sybase的 substring()
4.Oracle中 nvl() -- Sybase的 isnull()
5.Oracle取系統時間 sysdate -- Sybase的 getdate()
6.Oracle的decode -- Sybase的 case when then
--Oracle: select decode(param,null,resultA,resultB) from res;
--Sybase:select case when param is null then resultA else resultB end from res;
7.外連線
--Oracle:select * from tableA a ,tableB b where a.id=b.id(+);
--Sybase:select * from tableA a,tableB b where a.id*=b.id;
8.insert 方法
--Oracle:insert into tableA(select * from tableB where tableB.id="");
--Sybase:insert into tableA(id,name,age)(select * from tableB where tableB.id=""); insert的表必須寫清列名