天天看點

sysbase轉oracle,[原創]sysbase使用經驗

現在項目組使用的資料庫是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)相同

3)TRIM(exp) :去除兩邊空格

4)DATEFORMAT(date_exp,date_format) :日期型轉字元型;

5)STRING(exp):轉為字元型;

6)SUBSTRING(exp,int-exp1,):截取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]):進行數值型到字元型轉換;

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):字元轉日期型 或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

***   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():傳回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  NULL);

3.修改列的空與非空:

ALTER TABLE table_name MODIFY column_name  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);

---Sybase 遊标使用

Sybase  遊标使用例子

---遊标使用 (遊标名字為appeal_num_cursor)

DECLARE @serial_112 int, @dir_num  char(15),@complaint_time  datetime

--申明一個遊标

DECLARE  appeal_num_cursor  CURSOR

FOR SELECT  serial_112,dir_num,complaint_time FROM #iptv_guang  order by dir_num,complaint_time

--打開一個遊标

OPEN  appeal_num_cursor

--循環一個遊标

FETCH    appeal_num_cursor [email protected]_112,@dir_num,@complaint_time

WHILE @@SQLSTATUS = 0     -- @@FETCH_STATUS = 0  --

BEGIN

declare @c_num  int,@appeal_numint

select @c_num = appeal_num from#iptv_guang where dir_num = @dir_num

if @c_num = 0

begin

select @appeal_num= 1

end

else begin

select @appeal_num= @c_num + 1

end

update #iptv_guang

set appeal_num [email protected]_num

where dir_num = @dir_num and

complaint_time = @complaint_time  and

serial_112 = @serial_112

FETCH     appeal_num_cursor [email protected]_112, @dir_num,@complaint_time

END

--關閉遊标

CLOSE appeal_num_cursor

--釋放資源

DEALLOCATE cursor appeal_num_cursor

内容由使用者釋出,不代表本站觀點。如發現有害或侵權内容。請點選這裡