日本国产亚洲,中文精品一区二区三区,国产乱妇乱子在线播视频播放网站http://www.aygfsteel.com/rain1102/category/37647.html<br/><font color="green" style="font-family: 華文行楷;font-size:16px;">化學結構搜索,化學信息學,生物信息學,實驗室信息學等 。</font><br/><font color="#3C1435">以高科技的生物、化學信息技術實現生命科學領域中專業數據的計算和管理、提高研發能力、增強在科研和成本效率方面的國際競爭力,為生物、化學、醫藥和學術機構提供一流的解決方案和技術咨詢。</font><br/> <br/><font color="green" style="font-family: 華文行楷;font-size:16px;">子曰:危邦不入,亂邦不居。天下有道則見,無道則隱。</font><font color="#3C1435"></font><br/> zh-cnFri, 01 Jul 2011 01:09:53 GMTFri, 01 Jul 2011 01:09:53 GMT60存儲BitSet到MySQL中--相似度搜索http://www.aygfsteel.com/rain1102/archive/2011/06/29/353331.html周銳周銳Wed, 29 Jun 2011 02:20:00 GMThttp://www.aygfsteel.com/rain1102/archive/2011/06/29/353331.htmlhttp://www.aygfsteel.com/rain1102/comments/353331.htmlhttp://www.aygfsteel.com/rain1102/archive/2011/06/29/353331.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/353331.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/353331.htmlfingerprint是一個二進制數據,CDK中使用BitSet來存儲該信息,如果要每次比對都去生成BitSet,那也太耗時間了,所以我們需要存儲
fingerprint信息到數據庫中,比較的時候,直接讀取,而MySQL不支持存儲BitSet數據,網站找了一下,有人想到把
BitSet轉換成Blob信息進行存儲,然后取的時候再轉換回來,不愧是個好的方法。下面來看看代碼實現:

/*
 * Copyright (c) 2010-2020 Founder Ltd. All Rights Reserved.
 *
 * This software is the confidential and proprietary information of
 * Founder. You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the agreements
 * you entered into with Founder.
 *
 */
package com.founder.mysql;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.BitSet;
public class MySQLUtil {
public static Blob bitsetToBlob(BitSet myBitSet, Connection con) throws SQLException {
   byte[] byteArray = toByteArray(myBitSet);
   Blob blob = con.createBlob();
   blob.setBytes(1, byteArray);
   return blob;
}
private static byte[] toByteArray(BitSet bits) {
   byte[] bytes = new byte[bits.length()/8+1];
   for (int i=0; i<bits.length(); i++) {
       if (bits.get(i)) {
           bytes[bytes.length-i/8-1] |= 1<<(i%8);
       }
   }
   return bytes;
}
public static BitSet blobToBitSet(Blob blob) throws SQLException {
   byte[] bytes = blob.getBytes(1, (int)blob.length());
   BitSet bitSet = fromByteArray(bytes);
   return bitSet;
}
private static BitSet fromByteArray(byte[] bytes) {
   BitSet bits = new BitSet(1024);  
   for (int i=0; i<bytes.length*8; i++) {
       if ((bytes[bytes.length-i/8-1]&(1<<(i%8))) > 0) {
           bits.set(i);
       }
   }
   return bits;
}
}

通過以上代碼,我們就可以把fingerprint的值計算出來,然后存儲到MySQL數據庫中了。
進行相似度搜索的時候,值需要取出已經存儲的值進行比對就可以了。
float coefficient = Tanimoto.calculate(query, MySQLUtil.blobToBitSet(results.getBlob("bits")));
筆者測試了187586條結構數據,大概需要12秒左右,基本滿足一般需求。


周銳 2011-06-29 10:20 發表評論
]]>
如何調整MySQL 查詢緩沖【轉載】http://www.aygfsteel.com/rain1102/archive/2011/06/08/351942.html周銳周銳Wed, 08 Jun 2011 13:11:00 GMThttp://www.aygfsteel.com/rain1102/archive/2011/06/08/351942.htmlhttp://www.aygfsteel.com/rain1102/comments/351942.htmlhttp://www.aygfsteel.com/rain1102/archive/2011/06/08/351942.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/351942.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/351942.html

QueryCache(下面簡稱QC)是根據SQL語句來cache的。一個SQL查詢如果以select開頭,那么MySQL服務器將嘗試對其使用QC。每個Cache都是以SQL文本作為key來存的。在應用QC之前,SQL文本不會被作任何處理。也就是說,兩個SQL語句,只要相差哪怕是一個字 符(例如大小寫不一樣;多一個空格等),那么這兩個SQL將使用不同的一個CACHE。

不過SQL文本有可能會被客戶端做一些處理。例如在官方的命令行客戶端里,在發送SQL給服務器之前,會做如下處理: 
過濾所有注釋,去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中間的不會被去掉。

下面的三條SQL里,因為SELECT大小寫的關系,最后一條和其他兩條在QC里肯定是用的不一樣的存儲位置。而第一條和第二條,區別在于后者有個注釋, 在不同客戶端,會有不一樣的結果。所以,保險起見,請盡量不要使用動態的注釋。在PHP的mysql擴展里,SQL的注釋是不會被去掉的。也就是三條SQL會被存儲在三個不同的緩存里,雖然它們的結果都是一樣的。 
select * FROM people where name='surfchen'; 
select * FROM people where /*hey~*/name='surfchen'; 
SELECT * FROM people where name='surfchen';
 

目前只有select語句會被cache,其他類似show,use的語句則不會被cache。

因為QC是如此前端,如此簡單的一個緩存系統,所以如果一個表被更新,那么和這個表相關的SQL的所有QC都會被失效。假設一個聯合查詢里涉及到了表A和表B,如果表A或者表B的其中一個被更新(update或者delete),這個查詢的QC將會失效。

也就是說,如果一個表被頻繁更新,那么就要考慮清楚究竟是否應該對相關的一些SQL進行QC了。一個被頻繁更新的表如果被應用了QC,可能會加重數據庫的負擔,而不是減輕負擔。我一般的做法是默認打開QC,而對一些涉及頻繁更新的表的SQL語句加上SQL_NO_CACHE關鍵詞來對其禁用CACHE。這樣可以盡可能避免不必要的內存操作,盡可能保持內存的連續性。

那些查詢很分散的SQL語句,也不應該使用QC。例如用來查詢用戶和密碼的語句——“select pass from user where name='surfchen'”。這樣的語句,在一個系統里,很有可能只在一個用戶登陸的時候被使用。每個用戶的登陸所用到的查詢,都是不一樣的SQL 文本,QC在這里就幾乎不起作用了,因為緩存的數據幾乎是不會被用到的,它們只會在內存里占地方。


存儲塊,在本節里“存儲塊”和“block”是同一個意思。

QC緩存一個查詢結果的時候,一般情況下不是一次性地分配足夠多的內存來緩存結果的。而是在查詢結果獲得的過程中,逐塊存儲。當一個存儲塊被填滿之后,一個新的存儲塊將會被創建,并分配內存(allocate)。單個存儲塊的內存分配大小通過query_cache_min_res_unit參數控制,默認為4KB。最后一個存儲塊,如果不能被全部利用,那么沒使用的內存將會被釋放。如果被緩存的結果很大,那么可能會導致分配內存操作太頻繁,系統性能也隨之下降;而如果被緩存的結果都很小,那么可能會導致內存碎片過多,這些碎片如果太小,就很有可能不能再被分配使用。

除了查詢結果需要存儲塊之外,每個SQL文本也需要一個存儲塊,而涉及到的表也需要一個存儲塊(表的存儲塊是所有線程共享的,每個表只需要一個存儲塊)。 存儲塊總數量=查詢結果數量*2+涉及的數據庫表數量。也就是說,第一個緩存生成的時候,至少需要三個存儲塊:表信息存儲塊,SQL文本存儲塊,查詢結果存儲塊。而第二個查詢如果用的是同一個表,那么最少只需要兩個存儲塊:SQL文本存儲塊,查詢結果存儲塊。

通過觀察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每個緩存結果占用的存儲塊。它們的比例如果接近1:2,則說明當前的query_cache_min_res_unit參數已經足夠大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,則需要增加query_cache_min_res_unit的大小。

Qcache_queries_in_cache * query_cache_min_res_unit(sql文本和表信息所在的block占用的內存很小,可以忽略)如果遠遠大于query_cache_size - Qcache_free_memory,那么可以嘗試減小 query_cache_min_res_unit的值。


調整大小
如果Qcache_lowmem_prunes增長迅速,意味著很多緩存因為內存不夠而被釋放,而不是因為相關表被更新。嘗試加大query_cache_size,盡量使Qcache_lowmem_prunes零增長。


啟動參數
show variables like 'query_cache%' 可以看到這些信息。
query_cache_limit: 如果單個查詢結果大于這個值,則不Cache
query_cache_size: 分配給QC的內存。如果設為0,則相當于禁用QC。要注意QC必須使用大約40KB來存儲它的結構,如果設定小于 40KB,則相當于禁用QC。QC存儲的最小單位是1024 byte,所以如果你設定了一個不是1024的倍數的值,這個值會被四舍五入到最接近當前值的等于1024的倍數的值。 
query_cache_type: 0 完全禁止QC,不受SQL語句控制(另外可能要注意的是,即使這里禁用,上面一個參數所設定的內存大小還是會被分配);1啟用QC,可以在SQL語句使用 SQL_NO_CACHE禁用;2可以在SQL語句使用SQL_CACHE啟用。
query_cache_min_res_unit: 每次給QC結果分配內存的大小


狀態
show status like 'Qcache%' 可以看到這些信息。
Qcache_free_blocks: 當一個表被更新之后,和它相關的cache blocks將被free。但是這個block依然可能存在隊列中,除非是在隊列的尾部。這些blocks將會被統計到這個值來。可以用FLUSH QUERY CACHE語句來清空free blocks。
Qcache_free_memory: 可用內存,如果很小,考慮增加query_cache_size
Qcache_hits: 自mysql進程啟動起,cache的命中數量
Qcache_inserts: 自mysql進程啟動起,被增加進QC的數量
Qcache_lowmem_prunes: 由于內存過少而導致QC被刪除的條數。加大query_cache_size,盡可能保持這個值0增長。
Qcache_not_cached: 自mysql進程啟動起,沒有被cache的只讀查詢數量(包括select,show,use,desc等)
Qcache_queries_in_cache: 當前被cache的SQL數量
Qcache_total_blocks: 在QC中的blocks數。一個query可能被多個blocks存儲,而這幾個blocks中的最后一個未用滿的內存將會被釋放掉。例如一個QC結果要占6KB內存,如果query_cache_min_res_unit是4KB,則最后將會生成3個blocks,第一個block用來存儲sql語句文本,這個不會被統計到query_cache_size里,第二個block為4KB,第三個block為2KB(先allocate4KB,然后釋放多余的2KB)。每個表,當第一個和它有關的SQL查詢被CACHE的時候,會使用一個 block來存儲表信息。也就是說,block會被用在三處地方:表信息,SQL文本,查詢結果。

show global status like 'Com_select' 可以看到未中cache的查詢次數,包括讀寫查詢。

SELECT查詢的總數量等價于:

Com_select + Qcache_hits + queries with errors found by parser

Com_select的值等價于:

Qcache_inserts + Qcache_not_cached + queries with errors found during columns/rights check

常用計算公式:

Qcache命中率:Qcache_hits / (Com_select + Qcache_hits)

Qcache碎片率:Qcache_free_blocks / Qcache_total_blocks

Query結果集平均大小:(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache



周銳 2011-06-08 21:11 發表評論
]]>
mysql 百萬數據存儲過程 查詢優化技巧【轉載】http://www.aygfsteel.com/rain1102/archive/2011/05/20/350711.html周銳周銳Fri, 20 May 2011 14:00:00 GMThttp://www.aygfsteel.com/rain1102/archive/2011/05/20/350711.htmlhttp://www.aygfsteel.com/rain1102/comments/350711.htmlhttp://www.aygfsteel.com/rain1102/archive/2011/05/20/350711.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/350711.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/350711.html2.應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num is null
可以在num上設置默認值0,確保表中num列沒有null值,然后這樣查詢:
select id from t where num=0
3.應盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進行全表掃描。
4.應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描,如:
select id from t where num=10 or num=20
可以這樣查詢:
select id from t where num=10
union all
select id from t where num=20
5.in 和 not in 也要慎用,否則會導致全表掃描,如:
select id from t where num in(1,2,3)
對于連續的數值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
6.下面的查詢也將導致全表掃描:
select id from t where name like ‘%abc%’
若要提高效率,可以考慮全文檢索。
7.如果在 where
子句中使用參數,也會導致全表掃描。因為SQL只有在運行時才會解析局部變量,但優化程序不能將訪問計劃的選擇推遲到運行時;它必須在編譯時進行選擇。然而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項。如下面語句將進行全表掃描:
select id from t where num=@num <mailto:num=@num>
可以改為強制查詢使用索引:
select id from t with(index(索引名)) where num=@num <mailto:num=@num>
8.應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where num/2=100
應改為:
select id from t where num=100*2
9.應盡量避免在where子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。如:
select id from t where substring(name,1,3)=’abc’–name以abc開頭的id
select id from t where
datediff(day,createdate,’2005-11-30′)=0–‘2005-11-30’生成的id
應改為:
select id from t where name like ‘abc%’
select id from t where createdate>=’2005-11-30′ and createdate<’2005-12-1′
10.不要在 where 子句中的“=”左邊進行函數、算術運算或其他表達式運算,否則系統將可能無法正確使用索引。
11.在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引,否則該索引將不會被使用,并且應盡可能的讓字段順序與索引順序相一致。
12.不要寫一些沒有意義的查詢,如需要生成一個空表結構:
select col1,col2 into #t from t where 1=0
這類代碼不會返回任何結果集,但是會消耗系統資源的,應改成這樣:
create table #t(…)
13.很多時候用 exists 代替 in 是一個好的選擇:
select num from a where num in(select num from b)
用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
14.并不是所有索引對查詢都有效,SQL是根據表中數據來進行查詢優化的,當索引列有大量數據重復時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相應的 select 的效率,但同時也降低了 insert 及 update 的效率,因為 insert 或
update
時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數最好不要超過6個,若太多則應考慮一些不常使用到的列上建的索引是否有必要。
16.應盡可能的避免更新 clustered 索引數據列,因為 clustered
索引數據列的順序就是表記錄的物理存儲順序,一旦該列值改變將導致整個表記錄的順序的調整,會耗費相當大的資源。若應用系統需要頻繁更新 clustered
索引數據列,那么需要考慮是否應將該索引建為 clustered 索引。
17.盡量使用數字型字段,若只含數值信息的字段盡量不要設計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因為引擎在處理查詢和連接時會逐個比較字符串中每一個字符,而對于數字型而言只需要比較一次就夠了。
18.盡可能的使用 varchar/nvarchar 代替 char/nchar
,因為首先變長字段存儲空間小,可以節省存儲空間,其次對于查詢來說,在一個相對較小的字段內搜索效率顯然要高些。
19.任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
20.盡量使用表變量來代替臨時表。如果表變量包含大量數據,請注意索引非常有限(只有主鍵索引)。
21.避免頻繁創建和刪除臨時表,以減少系統表資源的消耗。
22.臨時表并不是不可使用,適當地使用它們可以使某些例程更有效,例如,當需要重復引用大型表或常用表中的某個數據集時。但是,對于一次性事件,最好使用導出表。
23.在新建臨時表時,如果一次性插入數據量很大,那么可以使用 select into 代替 create table,避免造成大量 log
,以提高速度;如果數據量不大,為了緩和系統表的資源,應先create table,然后insert。
24.如果使用到了臨時表,在存儲過程的最后務必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table
,這樣可以避免系統表的較長時間鎖定。
25.盡量避免使用游標,因為游標的效率較差,如果游標操作的數據超過1萬行,那么就應該考慮改寫。
26.使用基于游標的方法或臨時表方法之前,應先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。
27.與臨時表一樣,游標并不是不可使用。對小型數據集使用 FAST_FORWARD
游標通常要優于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數據時。在結果集中包括“合計”的例程通常要比使用游標執行的速度快。如果開發時間允許,基于游標的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。
28.在所有的存儲過程和觸發器的開始處設置 SET NOCOUNT ON ,在結束時設置 SET NOCOUNT OFF
。無需在執行存儲過程和觸發器的每個語句后向客戶端發送 DONE_IN_PROC 消息。
29.盡量避免大事務操作,提高系統并發能力。
30.盡量避免向客戶端返回大數據量,若數據量過大,應該考慮相應需求是否合理。

周銳 2011-05-20 22:00 發表評論
]]>
MySQL存儲過程中的3種循環【轉載】http://www.aygfsteel.com/rain1102/archive/2011/05/16/350301.html周銳周銳Mon, 16 May 2011 02:41:00 GMThttp://www.aygfsteel.com/rain1102/archive/2011/05/16/350301.htmlhttp://www.aygfsteel.com/rain1102/comments/350301.htmlhttp://www.aygfsteel.com/rain1102/archive/2011/05/16/350301.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/350301.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/350301.html

在MySQL存儲過程的語句中有三個標準的循環方式:WHILE循環,LOOP循環以及REPEAT循環。還有一種非標準的循環方式:GOTO,不過這種循環方式最好別用,很容易引起程序的混亂,在這里就不錯具體介紹了。

這幾個循環語句的格式如下:
WHILE……DO……END WHILE
REPEAT……UNTIL END REPEAT
LOOP……END LOOP
GOTO。

 

    下面首先使用第一種循環編寫一個例子。
mysql> create procedure pro10()
    -> begin
    -> declare i int;
    -> set i=0;
    -> while i<5 do
    ->     insert into t1(filed) values(i);
    ->     set i=i+1;
    -> end while;
    -> end;//
Query OK, 0 rows affected (0.00 sec)
    在這個例子中,INSERT和SET語句在WHILE和END WHILE之間,當變量i大于等于5的時候就退出循環。使用set i=0;語句是為了防止一個常見的錯誤,如果沒有初始化,i默認變量值為NULL,而NULL和任何值操作的結果都是NULL。
    執行一下這個存儲過程并產看一下執行結果:
mysql> delete from t1//
Query OK, 0 rows affected (0.00 sec)
mysql> call pro10()//
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1//
+——-+
| filed |
+——-+
    0 |
    1 |
    2 |
    3 |
    4 |
+——-+
5 rows in set (0.00 sec)
    以上就是執行結果,有5行數據插入到數據庫中,證明存儲過程編寫正確無誤^_^。

    再來看一下第二個循環控制指令 REPEAT……END REPEAT。使用REPEAT循環控制語句編寫下面這個存儲過程:
mysql> create procedure pro11()
    -> begin
    -> declare i int default 0;
    -> repeat
    ->     insert into t1(filed) values(i);
    ->     set i=i+1;
    ->     until i>=5
    -> end repeat;
    -> end;//
Query OK, 0 rows affected (0.00 sec)
    這個REPEAT循環的功能和前面WHILE循環一樣,區別在于它的執行后檢查是否滿足循環條件(until i>=5),而WHILE則是執行前檢查(while i<5 do)。
    不過要注意until i>=5后面不要加分號,如果加分號,就是提示語法錯誤。
    編寫完成后,調用一下這個存儲過程,并查看結果:
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)

mysql> call pro11()//
Query OK, 1 row affected (0.00 sec) #雖然在這里顯示只有一行數據受到影響,但是下面選擇數據的話,還是插入了5行數據。

mysql> select * from t1//
+——-+
| filed |
+——-+
    0 |
    1 |
    2 |
    3 |
    4 |
+——-+
5 rows in set (0.00 sec)
一行就是執行結果,實際的作用和使用while編寫的存儲過程一樣,都是插入5行數據。

再來看一下第三個循環控制語句LOOP……END LOOP。編寫一個存儲過程程序如下:
mysql> create procedure pro12()
    -> begin
    -> declare i int default 0;
    -> loop_label: loop
    ->     insert into t1(filed) values(i);
    ->     set i=i+1;
    ->     if i>=5 then
    ->         leave loop_label;
    ->     end if;
    -> end loop;
    -> end;//
Query OK, 0 rows affected (0.00 sec)
從上面這個例子可以看出,使用LOOP編寫同樣的循環控制語句要比使用while和repeat編寫的要復雜一些:在循環內部加入了IF……END IF語句,在IF語句中又加入了LEAVE語句,LEAVE語句的意思是離開循環,LEAVE的格式是:LEAVE 循環標號。
    編寫完存儲過程程序后,來執行并查看一下運行結果:
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)

 

mysql> call pro12//
Query OK, 1 row affected (0.00 sec) #雖然說只有一行數據受影響,但是實際上是插入了5行數據。

mysql> select * from t1//
+——-+
| filed |
+——-+
    0 |
    1 |
    2 |
    3 |
    4 |
+——-+
5 rows in set (0.00 sec)
    執行結果和使用WHILE、LOOP編寫的循環一樣,都是往標中插入5行值。

   Labels   標號和 END Labels 結束標號
   在使用loop的時候,使用到的labels標號,對于labels可以用到while,loop,rrepeat等循環控制語句中。而且有必要好好認識一下lables!!
mysql> create procedure pro13()
    -> label_1:begin
    -> label_2:while 0=1 do leave label_2;end while;
    -> label_3:repeat leave label_3;until 0=0 end repeat;
    -> label_4:loop leave label_4;end loop;
    -> end;//
Query OK, 0 rows affected (0.00 sec)
    上面這里例子顯示了可以在BEGIN、WHILE、REPEAT或者LOOP語句前使用語句標號,語句標號只能在合法的語句前使用,所以LEAVE label_3意味著離開語句標號名為label_3的語句或符合語句。
    其實,也可以使用END labels來表示標號結束符。
mysql> create procedure pro14()
    -> label_1:begin
    -> label_2:while 0=1 do leave label_2;end while label_2;
    -> label_3:repeat leave label_3;until 0=0 end repeat label_3;
    -> label_4:loop leave label_4;end loop label_4;
    -> end label_1;//
Query OK, 0 rows affected (0.00 sec)
    上面就是使用了標號結束符,其實這個結束標號并不是十分有用,而且他必須和開始定義的標號名字一樣,否則就會報錯。如果要養成一個良好的編程習慣方便他人閱讀的話,可以使用這個標號結束符。

ITERATE 迭代        
     如果是在ITERATE語句,即迭代語句中的話,就必須使用LEAVE語句。ITERATE只能出現在LOOP,REPEAT和WHILE語句中,它的意思是“再次循環”,例如:
mysql> create procedure pro15() 
    -> begin
    -> declare i int default 0;
    -> loop_label:loop
    ->     if i=3 then
    ->         set i=i+1;
    ->         iterate loop_label;
    ->     end if;
    ->     insert into t1(filed) values(i);
    ->     set i=i+1;
    ->     if i>=5 then
    ->        leave loop_label;
    ->     end if;
    ->   end loop;
    -> end;//
Query OK, 0 rows affected (0.00 sec)
    iterate語句和leave語句一樣,也是在循環內部使用,它有點類似于C/C++語言中的continue。
    那么這個存儲程序是怎么運行的的?首先i的值為0,條件判斷語句if i=3 then判斷為假,跳過if語段,向數據庫中插入0,然后i+1,同樣后面的if i>=5 then判斷也為假,也跳過;繼續循環,同樣插入1和2;在i=3的時候條件判斷語句if i=3 then判斷為真,執行i=i+1,i值為4,然后執行迭代iterate loop_label;,即語句執行到iterate loop_label;后直接跳到if i=3 then判斷語句,執行判斷,這個時候由于i=4,if i=3 then判斷為假,跳過IF語段,將4添加到表中,i變為5,條件判斷if i>=5 then判斷為真,執行leave loop_label;跳出loop循環,然后執行end;//,結束整個存儲過程。
    綜上所述,數據庫中將插入數值:0,1,2,4。執行存儲過程,并查看結果:|
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)

 

mysql> call pro15//
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1//
+——-+
| filed |
+——-+
    0 |
    1 |
    2 |
    4 |
+——-+
4 rows in set (0.00 sec)

和我們上面分析的結果一樣,只插入了數值0,1,2,4。



周銳 2011-05-16 10:41 發表評論
]]>
ERROR 1126 (HY000): Can't Open Shared Library(install UDF to mysql 5.1 in ubuntu 9.10)http://www.aygfsteel.com/rain1102/archive/2010/05/10/320485.html周銳周銳Mon, 10 May 2010 08:09:00 GMThttp://www.aygfsteel.com/rain1102/archive/2010/05/10/320485.htmlhttp://www.aygfsteel.com/rain1102/comments/320485.htmlhttp://www.aygfsteel.com/rain1102/archive/2010/05/10/320485.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/320485.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/320485.htmlit caused by ubuntu apparmor, so you just need to disable it.
touch /etc/apparmor.d/disable/usr.sbin.mysqld
/etc/init.d/apparmor restart
/etc/init.d/mysql restart
all above commands need root account.


周銳 2010-05-10 16:09 發表評論
]]>
在Ubuntu下使MySQL數據庫可以被遠程訪問http://www.aygfsteel.com/rain1102/archive/2010/04/09/317857.html周銳周銳Fri, 09 Apr 2010 07:49:00 GMThttp://www.aygfsteel.com/rain1102/archive/2010/04/09/317857.htmlhttp://www.aygfsteel.com/rain1102/comments/317857.htmlhttp://www.aygfsteel.com/rain1102/archive/2010/04/09/317857.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/317857.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/317857.html在Ubuntu下MySQL缺省是只允許本地訪問的,如果你要其他機器也能遠程夠訪問這臺Mysql數據庫的話,需要設置一些東西,下面我們一步步地來:

一、配置文件的修改
    1.#sudo vim /etc/mysql/my.cnf

    找到 bind-address = 127.0.0.1
    注釋掉這句話
 
二、Mysql數據庫的修改
1) [root@etc etc]# mysql -u  root  -p
Enter password:
2)mysql> use mysql;
3)mysql> select host,user,password from user;
4)grant all privileges on *.* to  root@192.168.15.101  identified by 'password'
 注意: (1)192.168.15.101是欲連接到此Mysql數據庫的客戶端的IP地址,而不是Mysql數據庫所在數據庫服務器的IP地址,切記。這里也可以使用'%'代替所有ip
              (2)password就是Mysql數據庫root用戶的password,根據實際情況需要修改

三、再次用Mysql客戶端登陸

 


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/bjblues/archive/2008/02/04/2083934.aspx



周銳 2010-04-09 15:49 發表評論
]]>
intersect in mysqlhttp://www.aygfsteel.com/rain1102/archive/2010/03/14/315404.html周銳周銳Sun, 14 Mar 2010 12:49:00 GMThttp://www.aygfsteel.com/rain1102/archive/2010/03/14/315404.htmlhttp://www.aygfsteel.com/rain1102/comments/315404.htmlhttp://www.aygfsteel.com/rain1102/archive/2010/03/14/315404.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/315404.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/315404.htmlAn INTERSECT is simply an inner join where we compare the tuples of one table with those of the other, and select those that appear in both while weeding out duplicates. So

select id, username from user where id>1
INTERSECT
select id, username from user where id<3

can simply be rewritten to

select id, username from user inner join
(select id, username from user where id <3) as b using (id, username)
where id>1

or
select a.id, a.username from
((select id, username from user where id > 1) as a
cross join
(select id, username from user where id <3) as b  on a.id = b.id)


周銳 2010-03-14 20:49 發表評論
]]>
MySQL序列解決方案[轉載]http://www.aygfsteel.com/rain1102/archive/2010/03/09/314917.html周銳周銳Tue, 09 Mar 2010 02:25:00 GMThttp://www.aygfsteel.com/rain1102/archive/2010/03/09/314917.htmlhttp://www.aygfsteel.com/rain1102/comments/314917.htmlhttp://www.aygfsteel.com/rain1102/archive/2010/03/09/314917.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/314917.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/314917.html原文地址: http://meetrice.javaeye.com/blog/89426

MySQL
自增長與Oracle序列的區別:
自增長只能用于表中的其中一個字段
自增長只能被分配給固定表的固定的某一字段,不能被多個表共用.
自增長會把一個未指定或NULL值的字段自動填上.

mysql中添加序列,請看下面的實例:
MYSQL里有這樣一張表:
Java代碼 復制代碼
  1. CREATE TABLE Movie(   
  2. id           INT NOT NULL AUTO_INCREMENT,   
  3. name     VARCHAR(60) NOT NULL,   
  4. released YEAR NOT NULL,   
  5. PRIMARY KEY (id)   
  6. ) ENGINE=InnoDB;  

Java代碼 復制代碼
  1. INSERT INTO Movie (name,released) VALUES ('Gladiator',2000);   
  2. INSERT INTO Movie (id,name,released) VALUES (NULL,'The Bourne Identity',1998);  

在ORACLE是這樣的:
Java代碼 復制代碼
  1. CREATE TABLE Movie(   
  2. id          INT NOT NULL,   
  3. name     VARCHAR2(60) NOT NULL,   
  4. released INT NOT NULL,   
  5. PRIMARY KEY (id)   
  6. );   
  7. CREATE SEQUENCE MovieSeq;  

Java代碼 復制代碼
  1. INSERT INTO Movie (id,name,released) VALUES (MovieSeq.NEXTVAL,'Gladiator',2000);  


在oracle下為表添加一個觸發器,就可以實現mysql自增長功能:
Java代碼 復制代碼
  1. CREATE OR REPLACE TRIGGER BRI_MOVIE_TRG   
  2. BEFORE INSERT ON Movie   
  3. FOR EACH ROW   
  4. BEGIN   
  5.   SELECT MovieSeq.NEXTVAL INTO :new.id FROM DUAL;   
  6. END BRI_MOVIE_TRG;   
  7. .   
  8. RUN;  

這樣,插件記錄就可以成為MYSQL風格:
Java代碼 復制代碼
  1. INSERT INTO Movie (name,released) VALUES ('The Lion King',1994);  


下面我們來看看如何在mysql數據里使用Oracle序列語法.NEXTVAL 和 .CURVAL.
我們假設在mysql中序列的語法是:

    NEXTVAL(’sequence’);
    CURRVAL(’sequence’);
    SETVAL(’sequence’,value);


下面就是CURRRVAL的實現方案:

Java代碼 復制代碼
  1. DROP TABLE IF EXISTS sequence;   
  2. CREATE TABLE sequence (   
  3. name              VARCHAR(50) NOT NULL,   
  4. current_value INT NOT NULL,   
  5. increment       INT NOT NULL DEFAULT 1,   
  6. PRIMARY KEY (name)   
  7. ) ENGINE=InnoDB;   
  8. INSERT INTO sequence VALUES ('MovieSeq',3,5);   
  9. DROP FUNCTION IF EXISTS currval;   
  10. DELIMITER $   
  11. CREATE FUNCTION currval (seq_name VARCHAR(50))   
  12. RETURNS INTEGER   
  13. CONTAINS SQL   
  14. BEGIN   
  15.   DECLARE value INTEGER;   
  16.   SET value = 0;   
  17.   SELECT current_value INTO value   
  18.   FROM sequence   
  19.   WHERE name = seq_name;   
  20.   RETURN value;   
  21. END$   
  22. DELIMITER ;  

測試一下結果:
Java代碼 復制代碼
  1. mysql> SELECT currval('MovieSeq');   
  2. +---------------------+   
  3. | currval('MovieSeq') |   
  4. +---------------------+   
  5. |                   3 |   
  6. +---------------------+   
  7. 1 row in set (0.00 sec)   
  8. mysql> SELECT currval('x');   
  9. +--------------+   
  10. | currval('x') |   
  11. +--------------+   
  12. |            0 |   
  13. +--------------+   
  14. 1 row in set, 1 warning (0.00 sec)   
  15. mysql> show warnings;   
  16. +---------+------+------------------+   
  17. | Level   | Code | Message          |   
  18. +---------+------+------------------+   
  19. | Warning | 1329 | No data to FETCH |   
  20. +---------+------+------------------+   
  21. 1 row in set (0.00 sec)  


nextval

Java代碼 復制代碼
  1. DROP FUNCTION IF EXISTS nextval;   
  2. DELIMITER $   
  3. CREATE FUNCTION nextval (seq_name VARCHAR(50))   
  4. RETURNS INTEGER   
  5. CONTAINS SQL   
  6. BEGIN   
  7.    UPDATE sequence   
  8.    SET          current_value = current_value + increment   
  9.    WHERE name = seq_name;   
  10.    RETURN currval(seq_name);   
  11. END$   
  12. DELIMITER ;  


Java代碼 復制代碼
  1. mysql> select nextval('MovieSeq');   
  2. +---------------------+   
  3. | nextval('MovieSeq') |   
  4. +---------------------+   
  5. |                  15 |   
  6. +---------------------+   
  7. 1 row in set (0.09 sec)   
  8.   
  9. mysql> select nextval('MovieSeq');   
  10. +---------------------+   
  11. | nextval('MovieSeq') |   
  12. +---------------------+   
  13. |                  20 |   
  14. +---------------------+   
  15. 1 row in set (0.01 sec)   
  16.   
  17. mysql> select nextval('MovieSeq');   
  18. +---------------------+   
  19. | nextval('MovieSeq') |   
  20. +---------------------+   
  21. |                  25 |   
  22. +---------------------+   
  23. 1 row in set (0.00 sec)  


setval
Java代碼 復制代碼
  1. DROP FUNCTION IF EXISTS setval;   
  2. DELIMITER $   
  3. CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)   
  4. RETURNS INTEGER   
  5. CONTAINS SQL   
  6. BEGIN   
  7.    UPDATE sequence   
  8.    SET          current_value = value   
  9.    WHERE name = seq_name;   
  10.    RETURN currval(seq_name);   
  11. END$   
  12. DELIMITER ;  


Java代碼 復制代碼
  1. mysql> select setval('MovieSeq',150);   
  2. +------------------------+   
  3. | setval('MovieSeq',150) |   
  4. +------------------------+   
  5. |                    150 |   
  6. +------------------------+   
  7. 1 row in set (0.06 sec)   
  8.   
  9. mysql> select curval('MovieSeq');   
  10. +---------------------+   
  11. | currval('MovieSeq') |   
  12. +---------------------+   
  13. |                 150 |   
  14. +---------------------+   
  15. 1 row in set (0.00 sec)   
  16.   
  17. mysql> select nextval('MovieSeq');   
  18. +---------------------+   
  19. | nextval('MovieSeq') |   
  20. +---------------------+   
  21. |                 155 |   
  22. +---------------------+   
  23. 1 row in set (0.00 sec)  


周銳 2010-03-09 10:25 發表評論
]]>
項目中遇到的性能問題總結http://www.aygfsteel.com/rain1102/archive/2009/08/05/289965.html周銳周銳Wed, 05 Aug 2009 08:27:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/08/05/289965.htmlhttp://www.aygfsteel.com/rain1102/comments/289965.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/08/05/289965.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/289965.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/289965.html最近一直從事的項目中遇到不少性能問題, 雖然表中的數據數量不是太大, 最大也就200萬條, 其他基本都是100萬左右, 但由于存在一個化合物結構信息的數據使得數據庫特別的大, 就dmp文件就達到4G多。而客戶對性能要求又比較高。目前遇到問題以及解決方案(并非最佳方案)總結如下:

1. 多表查詢時候速度慢: 為表之間關聯列創建索引, 只取需要數據。
2. 多條數據批量更新: 盡量使用原生SQL, 少用Hibernate取了循環再更新。
3. 數據量大查詢時候少用upper,lower等類似數據提供的功能函數去轉換數據,可以考慮是否在存入數據之前就把所有數據改為大寫或者小寫,顯示時候再按要求格式化內容。
4. 使用Hibernate時候,把關聯關系盡量設置成延遲加載,然后使用時候再用fetch取出。

目前先總結這些, 遇到再加。

周銳 2009-08-05 16:27 發表評論
]]>
使用CSVJDBC導入CSV文件數據到MySQL中http://www.aygfsteel.com/rain1102/archive/2009/08/04/289730.html周銳周銳Tue, 04 Aug 2009 03:27:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/08/04/289730.htmlhttp://www.aygfsteel.com/rain1102/comments/289730.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/08/04/289730.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/289730.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/289730.html

package com.founder.demo;

import Java.sql.Connection;
import Java.sql.DriverManager;
import Java.sql.PreparedStatement;
import Java.sql.ResultSet;
import Java.sql.Statement;

public class ImportCSV {

 public static void main(String[] args) {
  try {
   // load the driver into memory
   Class.forName("org.relique.jdbc.csv.CsvDriver");

   // create a connection. The first command line parameter is assumed to
   //  be the directory in which the .csv files are held
   Connection conn = DriverManager
     .getConnection("jdbc:relique:csv:H:\\PythonWorkSpace");

   // create a Statement object to execute the query with
   Statement stmt = conn.createStatement();

   // Select the columns from csv file
   ResultSet results = stmt
     .executeQuery("SELECT ORDER_NO,ARTICLE_NO,CATALOG_NO,DESCRIPTION,QUANTITY,ISO_UNIT,UNIT,MDL_NO,CAS, "
       + " MOLECULA,FORMULA,DENSITY,PRICE_EUR,UN_NO,DANGER_GR,DANGER_CLASS,ZUSATZGEFAHR1,ZUSATZGEFAHR2,R_PHRASES, "
       + " S_PHRASES,DANGER_SYMBOL,STORAGE_TEMPERATURE FROM ABCR");
   
   //MySQL
   Class.forName("com.mysql.jdbc.Driver").newInstance();
   Connection con = Java.sql.DriverManager
     .getConnection(
       "jdbc:mysql://localhost/chemicaldb?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull",
       "root", "root");

   String sql = "INSERT INTO meryer_abcr (ORDER_NO,ARTICLE_NO,CATALOG_NO,DESCRIPTION,QUANTITY,ISO_UNIT,UNIT,MDL_NO,CAS, "
     + " MOLECULA_FORMULA,MOLECULAR_WEIGHT,DENSITY,PRICE_EUR,UN_NO,DANGER_GROUP,DANGER_CLASS,ZUSATZGEFAHR1,ZUSATZGEFAHR2,R_PHRASES, "
     + " S_PHRASES,DANGER_SYMBOL,STORAGE_TEMPERATURE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

   PreparedStatement mstmt = con.prepareStatement(sql);

   // dump out the results and set params
   while (results.next()) {
    mstmt.setString(1, results.getString("ORDER_NO"));
    mstmt.setString(2, results.getString("ARTICLE_NO"));
    mstmt.setString(3, results.getString("CATALOG_NO"));
    mstmt.setString(4, results.getString("DESCRIPTION"));
    mstmt.setString(5, results.getString("QUANTITY"));
    mstmt.setString(6, results.getString("ISO_UNIT"));
    mstmt.setString(7, results.getString("UNIT"));
    mstmt.setString(8, results.getString("MDL_NO"));
    mstmt.setString(9, results.getString("CAS"));
    mstmt.setString(10, results.getString("MOLECULA_FORMULA"));
    mstmt.setString(11, results.getString("MOLECULAR_WEIGHT"));
    mstmt.setString(12, results.getString("DENSITY"));
    mstmt.setString(13, results.getString("PRICE_EUR"));
    mstmt.setString(14, results.getString("UN_NO"));
    mstmt.setString(15, results.getString("DANGER_GROUP"));
    mstmt.setString(16, results.getString("DANGER_CLASS"));
    mstmt.setString(17, results.getString("ZUSATZGEFAHR1"));
    mstmt.setString(18, results.getString("ZUSATZGEFAHR2"));
    mstmt.setString(19, results.getString("R_PHRASES"));
    mstmt.setString(20, results.getString("S_PHRASES"));
    mstmt.setString(21, results.getString("DANGER_SYMBOL"));
    mstmt.setString(22, results.getString("STORAGE_TEMPERATURE"));
    mstmt.execute();
    
    System.out.println(results.getString("ORDER_NO"));
   }
   
   // clean up
   mstmt.close();
   con.close();
   results.close();
   stmt.close();
   conn.close();
  } catch (Exception e) {
   System.out.println("Oops-> " + e);
  }

 }

}

其實很簡單,和操作數據庫一樣,提供了類似數據中的SQL語句來操作CSV文件中的數據。



周銳 2009-08-04 11:27 發表評論
]]>
MySQL中同步兩個表中的某些字段http://www.aygfsteel.com/rain1102/archive/2009/07/31/289324.html周銳周銳Fri, 31 Jul 2009 14:14:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/07/31/289324.htmlhttp://www.aygfsteel.com/rain1102/comments/289324.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/07/31/289324.html#Feedback2http://www.aygfsteel.com/rain1102/comments/commentRss/289324.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/289324.html以前我們在寫update的時候往往是使用 update tablename set columnname = value這樣的簡單語法,而今天遇到一個需求,根據一張表中的數據來更新另外一張表中的某些字段值,比如有個A表和B表,A中有字段id,name,email,phone,cno,這里的cno也是唯一的,B表中有id,othercloumn,email,phone,cno,這時候想通過B中的email和phone值來更新A中的email和phone值。我們可以使用一下語句實現這個功能:

update A, B set
A.email= B.email, A.phone= B.phone
where A.cno=B.cno


Oracle中可以如下方式實現:
update A set
(email, phone) = (select B.email, B.phone where B.cno= A.cno)



周銳 2009-07-31 22:14 發表評論
]]>
Python發送Post請求http://www.aygfsteel.com/rain1102/archive/2009/07/28/288723.html周銳周銳Tue, 28 Jul 2009 06:32:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/07/28/288723.htmlhttp://www.aygfsteel.com/rain1102/comments/288723.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/07/28/288723.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/288723.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/288723.html由于有很多數據需要逐個翻譯,手工處理比較麻煩,花了十來分鐘寫了個python程序去跑,輕松了很多。具體代碼如下:

#encoding=utf-8
from __future__ import with_statement
import MySQLdb
import urllib
from lister import ListerTR

conn = MySQLdb.connect(host="localhost", user="root", passwd="root", db="coocoo", charset="utf8")
cursor = conn.cursor()
cursor.execute("select id, enname from compound where enname != '' and zhname = '' order by id")
row=cursor.fetchall()
for r in row:
    params = urllib.urlencode({'eng2chi':r[1]})      這里組織參數
    sock = urllib.urlopen("http://202.127.145.134/scdb/translate/translate.asp", params)   發送請求,并把參數傳過去
    html = sock.read()
    sock.close()
    p = ListerTR()   以下為解析返回的數據代碼
    p.feed(html)
    html = p.html
    if u"成功" in html:
        value = p.values[5]
        data = value.strip()
        print r[0], r[1], data    取回翻譯成功的內容更新數據庫里面的值
        cursor.execute("update compound set zhname = %s where id=%s", (data, r[0]))
        conn.commit()
    else:    把翻譯失敗的記錄給文本文件中
        with open('failture.txt', 'a+') as f:
            f.write(str(r[0])+" | "+str(r[1]))
            f.write('\n')
cursor.close()
conn.close()



周銳 2009-07-28 14:32 發表評論
]]>
在MySQL和Oracle中實現行合并http://www.aygfsteel.com/rain1102/archive/2009/06/24/283867.html周銳周銳Wed, 24 Jun 2009 01:18:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/06/24/283867.htmlhttp://www.aygfsteel.com/rain1102/comments/283867.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/06/24/283867.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/283867.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/283867.html 表結構以及數據如下:
id  name       email
1   eric         zhourui@founder.com
2   maggie    maggie@163.com
3   scott       scott@yahoo.com
4   eric         eric@163.com
我想的到如下數據
eric           zhourui@founder.com,eric@163.com
maggie      maggie@163.com
scott         scott@yahoo.com

如果使用MySQL, 則實現語句如下:
select name , group_concat(email order by email separator ", ") as email from student group by name

如果以上效果想在Oracle中顯示, 則比較復雜點了, 因為Oracle中沒有行合并函數, 則需要使用sys_connect_by_path()來實現, 代碼如下:
select name, ltrim(sys_connect_by_path(email,','),',') email from(
select name,email,
row_number() over(partition by name order by email) rn,
count(*) over(partition by name) cnt
from student
) where level = cnt
start with rn = 1
connect by prior name = name and prior rn + 1 = rn

周銳 2009-06-24 09:18 發表評論
]]>
將Clob類型數據轉換成字符串類型http://www.aygfsteel.com/rain1102/archive/2009/06/03/279816.html周銳周銳Wed, 03 Jun 2009 07:11:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/06/03/279816.htmlhttp://www.aygfsteel.com/rain1102/comments/279816.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/06/03/279816.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/279816.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/279816.html dbms_lob.substr(clobcloum,2000,1)

select id, name, coden
  from cims_supplier
 where name like 'A%'
   and coden like 'A%'
union
select cdbregno      as id,
       dbms_lob.substr(supplier_name,2000,1) as name,
       coden         as coden
  from acdsupplier_moltable
 where supplier_name like 'A%'
   and coden like 'A%'

cims_supplier表中的name是varchar2類型, 而acdsupplier_moltable表中的supplier_name為clob類型, 這樣就可以union了.
當然排序也可以了.
select * from t1 order by dbms_lob.substr(clobcloum,2000,1);



周銳 2009-06-03 15:11 發表評論
]]>
Mysql5主從同步配置http://www.aygfsteel.com/rain1102/archive/2009/04/15/265743.html周銳周銳Wed, 15 Apr 2009 06:02:00 GMThttp://www.aygfsteel.com/rain1102/archive/2009/04/15/265743.htmlhttp://www.aygfsteel.com/rain1102/comments/265743.htmlhttp://www.aygfsteel.com/rain1102/archive/2009/04/15/265743.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/265743.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/265743.html一. 安裝包選擇:

      mysql-5.0.19.tar.gz

二. 安裝環境:

主服務器:   192.168.0.201

從服務器:   192.168.0.00

三.主服務器配置:

Ø         建立用戶
grant replication slave on *.* to user001@192.168.0.200 identified by ‘111111′

Ø         編輯配置文件/etc/my.cnf
server-id = 1
log-bin=mysql-bin
binlog-do-db=test
binlog-ignore-db=mysql

 

注:

 # grant replication slave on *.* to ‘用戶名’@'主機’ identified by ‘密碼’;
# binlog-do-db=需要備份的數據庫名,可寫多行
# binlog-ignore-db=不需要備份的數據庫名,可寫多行

       # 可在B Slave上做連接測試: mysql -h 192.168.0.200 -u test -p

四.從服務器配置:

Ø        編輯/etc/my.cnf

server-id=2
server-id=2       記得是兩個???
log-bin=mysql-bin
master-host=192.168.0.201
master-user=user001
master-password=111111
master-port=3306
replicate-do-db=test
replicate-do-db=test1
# replicate-do-db=test  需要備份的數據庫名
# replicate-ignore-db=mysql 忽略的數據庫
# master-connect-retry=60 如果從服務器發現主服務器斷掉,重新連接的時間差(秒)

先手動同步一下主從服務器中要備份的數據庫,再重啟主,從服務器。

五.驗證是否配置正確:

     # mysql>  slave start;

     # mysql>  show slave status\G;

*************************** 1. row ***************************

             Slave_IO_State: Waiting for master to send event

                Master_Host: 192.168.0.201

                Master_User: repluser1

                Master_Port: 3306

              Connect_Retry: 60

            Master_Log_File: mysql-bin.000045

        Read_Master_Log_Pos: 212

             Relay_Log_File: sky-relay-bin.000054

              Relay_Log_Pos: 235

      Relay_Master_Log_File: mysql-bin.000045

           Slave_IO_Running: Yes

          Slave_SQL_Running: Yes

            Replicate_Do_DB: test,test1

        Replicate_Ignore_DB:

         Replicate_Do_Table:

     Replicate_Ignore_Table:

    Replicate_Wild_Do_Table:

Replicate_Wild_Ignore_Table:

                 Last_Errno: 0

                 Last_Error:

               Skip_Counter: 0

        Exec_Master_Log_Pos: 212

            Relay_Log_Space: 235

            Until_Condition: None

             Until_Log_File:

              Until_Log_Pos: 0

         Master_SSL_Allowed: No

         Master_SSL_CA_File:

         Master_SSL_CA_Path:

            Master_SSL_Cert:

          Master_SSL_Cipher:

             Master_SSL_Key:

      Seconds_Behind_Master: 0

1 row in set (0.00 sec)

確如如下行一致:
Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

其他: ++主服務器上的相關命令
show master status
show slave hosts
show logs
show binlog events
purge logs to ‘log_name’
purge logs before ‘date’
reset master(老版本flush master)
set sql_log_bin=

++從服務器上的相關命令
slave start
slave stop
SLAVE STOP IO_THREAD //此線程把master段的日志寫到本地
SLAVE start IO_THREAD
SLAVE STOP SQL_THREAD //此線程把寫到本地的日志應用于數據庫
SLAVE start SQL_THREAD
reset slave
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
load data from master
show slave status(SUPER,REPLICATION CLIENT)
CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,MASTER_USER=, MASTER_PASSWORD= //動態改變master信息
PURGE MASTER [before ‘date’] 刪除master端已同步過的日志

++產生了mysql-bin.00000x文件可以刪除

 

附一: mysql無法啟動:

# /usr/local/mysql//bin/mysqld_safe --user=mysql --log-error=err.txt

# more err.txt 根據里面的提示信息進行判斷分析

 

附二: 解決mysql“Access denied for user 'root'@'localhost'”

mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
修改root用戶的密碼:
# mysqladmin -uroot -p password 'newpassword' -

文章出處:http://www.diybl.com/course/6_system/linux/Linuxjs/2008622/127458.html



周銳 2009-04-15 14:02 發表評論
]]>
MySQL外部訪問http://www.aygfsteel.com/rain1102/archive/2008/12/19/247350.html周銳周銳Fri, 19 Dec 2008 07:41:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/12/19/247350.htmlhttp://www.aygfsteel.com/rain1102/comments/247350.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/12/19/247350.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/247350.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/247350.html 如下:
mysql>use mysql;
mysql>grant all privileges on 數據庫名字.* to '遠程用戶名'@'遠程IP地址' identified by '遠程用戶的密碼';
mysql>flush privileges;
mysql>\q



周銳 2008-12-19 15:41 發表評論
]]>
Mysql日期和時間函數http://www.aygfsteel.com/rain1102/archive/2008/12/12/245840.html周銳周銳Fri, 12 Dec 2008 01:50:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/12/12/245840.htmlhttp://www.aygfsteel.com/rain1102/comments/245840.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/12/12/245840.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/245840.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/245840.html
mysql> SELECT something FROM table 
WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30; 

DAYOFWEEK(date) 
返回日期date的星期索引(1=星期天,2=星期一, ……7=星期六)。這些索引值對應于ODBC標準。 
mysql> select DAYOFWEEK('1998-02-03'); 
-> 3 

WEEKDAY(date) 
返回date的星期索引(0=星期一,1=星期二, ……6= 星期天)。 
mysql> select WEEKDAY('1997-10-04 22:23:00'); 
-> 5 
mysql> select WEEKDAY('1997-11-05'); 
-> 2 

DAYOFMONTH(date) 
返回date的月份中日期,在1到31范圍內。 
mysql> select DAYOFMONTH('1998-02-03'); 
-> 3 

DAYOFYEAR(date) 
返回date在一年中的日數, 在1到366范圍內。 
mysql> select DAYOFYEAR('1998-02-03'); 
-> 34 

MONTH(date) 
返回date的月份,范圍1到12。 
mysql> select MONTH('1998-02-03'); 
-> 2 

DAYNAME(date) 
返回date的星期名字。 
mysql> select DAYNAME("1998-02-05"); 
-> 'Thursday' 

MONTHNAME(date) 
返回date的月份名字。 
mysql> select MONTHNAME("1998-02-05"); 
-> 'February' 

QUARTER(date) 
返回date一年中的季度,范圍1到4。 
mysql> select QUARTER('98-04-01'); 
-> 2 

WEEK(date) 
  
WEEK(date,first) 
對于星期天是一周的第一天的地方,有一個單個參數,返回date的周數,范圍在0到52。2個參數形式WEEK()允許
你指定星期是否開始于星期天或星期一。如果第二個參數是0,星期從星期天開始,如果第二個參數是1,
從星期一開始。 
mysql> select WEEK('1998-02-20'); 
-> 7 
mysql> select WEEK('1998-02-20',0); 
-> 7 
mysql> select WEEK('1998-02-20',1); 
-> 8 

YEAR(date) 
返回date的年份,范圍在1000到9999。 
mysql> select YEAR('98-02-03'); 
-> 1998 

HOUR(time) 
返回time的小時,范圍是0到23。 
mysql> select HOUR('10:05:03'); 
-> 10 

MINUTE(time) 
返回time的分鐘,范圍是0到59。 
mysql> select MINUTE('98-02-03 10:05:03'); 
-> 5 

SECOND(time) 
回來time的秒數,范圍是0到59。 
mysql> select SECOND('10:05:03'); 
-> 3 

PERIOD_ADD(P,N) 
增加N個月到階段P(以格式YYMM或YYYYMM)。以格式YYYYMM返回值。注意階段參數P不是日期值。 
mysql> select PERIOD_ADD(9801,2); 
-> 199803 

PERIOD_DIFF(P1,P2) 
返回在時期P1和P2之間月數,P1和P2應該以格式YYMM或YYYYMM。注意,時期參數P1和P2不是日期值。 
mysql> select PERIOD_DIFF(9802,199703); 
-> 11 

DATE_ADD(date,INTERVAL expr type) 
  
DATE_SUB(date,INTERVAL expr type) 
  
ADDDATE(date,INTERVAL expr type) 
  
SUBDATE(date,INTERVAL expr type) 
這些功能執行日期運算。對于MySQL 3.22,他們是新的。ADDDATE()和SUBDATE()是DATE_ADD()和DATE_SUB()的同義詞。
在MySQL 3.23中,你可以使用+和-而不是DATE_ADD()和DATE_SUB()。(見例子)date是一個指定開始日期的
DATETIME或DATE值,expr是指定加到開始日期或從開始日期減去的間隔值一個表達式,expr是一個字符串;它可以以
一個“-”開始表示負間隔。type是一個關鍵詞,指明表達式應該如何被解釋。EXTRACT(type FROM date)函數從日期
中返回“type”間隔。下表顯示了type和expr參數怎樣被關聯: type值 含義 期望的expr格式 
SECOND 秒 SECONDS 
MINUTE 分鐘 MINUTES 
HOUR 時間 HOURS 
DAY 天 DAYS 
MONTH 月 MONTHS 
YEAR 年 YEARS 
MINUTE_SECOND 分鐘和秒 "MINUTES:SECONDS" 
HOUR_MINUTE 小時和分鐘 "HOURS:MINUTES" 
DAY_HOUR 天和小時 "DAYS HOURS" 
YEAR_MONTH 年和月 "YEARS-MONTHS" 
HOUR_SECOND 小時, 分鐘, "HOURS:MINUTES:SECONDS" 
DAY_MINUTE 天, 小時, 分鐘 "DAYS HOURS:MINUTES" 
DAY_SECOND 天, 小時, 分鐘, 秒 "DAYS HOURS:MINUTES:SECONDS" 

MySQL在expr格式中允許任何標點分隔符。表示顯示的是建議的分隔符。如果date參數是一個DATE值并且你的計算僅僅
包含YEAR、MONTH和DAY部分(即,沒有時間部分),結果是一個DATE值。否則結果是一個DATETIME值。 

mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND; 
-> 1998-01-01 00:00:00 
mysql> SELECT INTERVAL 1 DAY + "1997-12-31"; 
-> 1998-01-01 
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND; 
-> 1997-12-31 23:59:59 
mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
INTERVAL 1 SECOND); 
-> 1998-01-01 00:00:00 
mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
INTERVAL 1 DAY); 
-> 1998-01-01 23:59:59 
mysql> SELECT DATE_ADD("1997-12-31 23:59:59", 
INTERVAL "1:1" MINUTE_SECOND); 
-> 1998-01-01 00:01:00 
mysql> SELECT DATE_SUB("1998-01-01 00:00:00", 
INTERVAL "1 1:1:1" DAY_SECOND); 
-> 1997-12-30 22:58:59 
mysql> SELECT DATE_ADD("1998-01-01 00:00:00", 
INTERVAL "-1 10" DAY_HOUR); 
-> 1997-12-30 14:00:00 
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY); 
-> 1997-12-02 
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02"); 
-> 1999 
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03"); 
-> 199907 
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03"); 
-> 20102 

如果你指定太短的間隔值(不包括type關鍵詞期望的間隔部分),MySQL假設你省掉了間隔值的最左面部分。例如,
如果你指定一個type是DAY_SECOND,值expr被希望有天、小時、分鐘和秒部分。如果你象"1:10"這樣指定值,
MySQL假設日子和小時部分是丟失的并且值代表分鐘和秒。換句話說,"1:10" DAY_SECOND以它等價于"1:10" MINUTE_SECOND
的方式解釋,這對那MySQL解釋TIME值表示經過的時間而非作為一天的時間的方式有二義性。如果你使用確實不正確的日期,
結果是NULL。如果你增加MONTH、YEAR_MONTH或YEAR并且結果日期大于新月份的最大值天數,日子在新月用最大的天調整。 

mysql> select DATE_ADD('1998-01-30', Interval 1 month); 
-> 1998-02-28 

注意,從前面的例子中詞INTERVAL和type關鍵詞不是區分大小寫的。 
TO_DAYS(date) 
給出一個日期date,返回一個天數(從0年的天數)。 
mysql> select TO_DAYS(950501); 
-> 728779 
mysql> select TO_DAYS('1997-10-07'); 
-> 729669 

TO_DAYS()不打算用于使用格列高里歷(1582)出現前的值。 

FROM_DAYS(N) 
給出一個天數N,返回一個DATE值。 
mysql> select FROM_DAYS(729669); 
-> '1997-10-07' 

TO_DAYS()不打算用于使用格列高里歷(1582)出現前的值。 

DATE_FORMAT(date,format) 
根據format字符串格式化date值。下列修飾符可以被用在format字符串中: %M 月名字(January……December) 
%W 星期名字(Sunday……Saturday) 
%D 有英語前綴的月份的日期(1st, 2nd, 3rd, 等等。) 
%Y 年, 數字, 4 位 
%y 年, 數字, 2 位 
%a 縮寫的星期名字(Sun……Sat) 
%d 月份中的天數, 數字(00……31) 
%e 月份中的天數, 數字(0……31) 
%m 月, 數字(01……12) 
%c 月, 數字(1……12) 
%b 縮寫的月份名字(Jan……Dec) 
%j 一年中的天數(001……366) 
%H 小時(00……23) 
%k 小時(0……23) 
%h 小時(01……12) 
%I 小時(01……12) 
%l 小時(1……12) 
%i 分鐘, 數字(00……59) 
%r 時間,12 小時(hh:mm:ss [AP]M) 
%T 時間,24 小時(hh:mm:ss) 
%S 秒(00……59) 
%s 秒(00……59) 
%p AM或PM 
%w 一個星期中的天數(0=Sunday ……6=Saturday ) 
%U 星期(0……52), 這里星期天是星期的第一天 
%u 星期(0……52), 這里星期一是星期的第一天 
%% 一個文字“%”。 

所有的其他字符不做解釋被復制到結果中。 

mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y'); 
-> 'Saturday October 1997' 
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s'); 
-> '22:23:00' 
mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
'%D %y %a %d %m %b %j'); 
-> '4th 97 Sat 04 10 Oct 277' 
mysql> select DATE_FORMAT('1997-10-04 22:23:00', 
'%H %k %I %r %T %S %w'); 
-> '22 22 10 10:23:00 PM 22:23:00 00 6' 
MySQL3.23中,在格式修飾符字符前需要%。在MySQL更早的版本中,%是可選的。 

TIME_FORMAT(time,format) 
這象上面的DATE_FORMAT()函數一樣使用,但是format字符串只能包含處理小時、分鐘和秒的那些格式修飾符。
其他修飾符產生一個NULL值或0。 
CURDATE() 
  
CURRENT_DATE 
以'YYYY-MM-DD'或YYYYMMDD格式返回今天日期值,取決于函數是在一個字符串還是數字上下文被使用。 
mysql> select CURDATE(); 
-> '1997-12-15' 
mysql> select CURDATE() + 0; 
-> 19971215 

CURTIME() 
  
CURRENT_TIME 
以'HH:MM:SS'或HHMMSS格式返回當前時間值,取決于函數是在一個字符串還是在數字的上下文被使用。 
mysql> select CURTIME(); 
-> '23:50:26' 
mysql> select CURTIME() + 0; 
-> 235026 

NOW() 
  
SYSDATE() 
  
CURRENT_TIMESTAMP 
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回當前的日期和時間,取決于函數是在一個字符串還是在數字的
上下文被使用。 
mysql> select NOW(); 
-> '1997-12-15 23:50:26' 
mysql> select NOW() + 0; 
-> 19971215235026 

UNIX_TIMESTAMP() 
  
UNIX_TIMESTAMP(date) 
如果沒有參數調用,返回一個Unix時間戳記(從'1970-01-01 00:00:00'GMT開始的秒數)。如果UNIX_TIMESTAMP()用一
個date參數被調用,它返回從'1970-01-01 00:00:00' GMT開始的秒數值。date可以是一個DATE字符串、一個DATETIME
字符串、一個TIMESTAMP或以YYMMDD或YYYYMMDD格式的本地時間的一個數字。 
mysql> select UNIX_TIMESTAMP(); 
-> 882226357 
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00'); 
-> 875996580 

當UNIX_TIMESTAMP被用于一個TIMESTAMP列,函數將直接接受值,沒有隱含的“string-to-unix-timestamp”變換。 

FROM_UNIXTIME(unix_timestamp) 
以'YYYY-MM-DD HH:MM:SS'或YYYYMMDDHHMMSS格式返回unix_timestamp參數所表示的值,取決于函數是在一個字符串
還是或數字上下文中被使用。 
mysql> select FROM_UNIXTIME(875996580); 
-> '1997-10-04 22:23:00' 
mysql> select FROM_UNIXTIME(875996580) + 0; 
-> 19971004222300 

FROM_UNIXTIME(unix_timestamp,format) 
返回表示 Unix 時間標記的一個字符串,根據format字符串格式化。format可以包含與DATE_FORMAT()函數列出的條
目同樣的修飾符。 
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(), 
'%Y %D %M %h:%i:%s %x'); 
-> '1997 23rd December 03:43:30 x' 

SEC_TO_TIME(seconds) 
返回seconds參數,變換成小時、分鐘和秒,值以'HH:MM:SS'或HHMMSS格式化,取決于函數是在一個字符串還是在數字
上下文中被使用。 
mysql> select SEC_TO_TIME(2378); 
-> '00:39:38' 
mysql> select SEC_TO_TIME(2378) + 0; 
-> 3938 

TIME_TO_SEC(time) 
返回time參數,轉換成秒。 
mysql> select TIME_TO_SEC('22:23:00'); 
-> 80580 
mysql> select TIME_TO_SEC('00:39:38'); 
-> 2378

獲取當前
select current_date;
select current_time;

周銳 2008-12-12 09:50 發表評論
]]>
MySQL查詢區分大小寫http://www.aygfsteel.com/rain1102/archive/2008/12/10/245562.html周銳周銳Wed, 10 Dec 2008 12:32:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/12/10/245562.htmlhttp://www.aygfsteel.com/rain1102/comments/245562.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/12/10/245562.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/245562.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/245562.htmlCREATE TABLE students(
    name VARCHAR(10)
);
mysql查詢默認是不區分大小寫的 如:
select * from students where name like 'a%'
select * from students where name like 'A%'
效果是一樣的。
要讓mysql查詢區分大小寫,可以:
select * from students where binary name like 'a%'
select * from students where binary name like 'A%'

另一種辦法是在數據庫設計的時候,可能需要大小寫敏感,解決方法是建表時候使用BINARY標示。
CREATE TABLE students(
    name VARCHAR(10) BINARY
);


如果修改已經存在的字段,使用如下SQL語句:
alter table ecs_users change user_name user_name varchar(60) binary default '' not null

周銳 2008-12-10 20:32 發表評論
]]>
SQL中Case的使用方法(下篇) (轉載)http://www.aygfsteel.com/rain1102/archive/2008/09/24/230840.html周銳周銳Wed, 24 Sep 2008 03:29:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/09/24/230840.htmlhttp://www.aygfsteel.com/rain1102/comments/230840.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/09/24/230840.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/230840.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/230840.html四,根據條件有選擇的UPDATE。

例,有如下更新條件
  1. 工資5000以上的職員,工資減少10%
  2. 工資在2000到4600之間的職員,工資增加15%
很容易考慮的是選擇執行兩次UPDATE語句,如下所示
--條件1
UPDATE Personnel
SET salary = salary * 0.9
WHERE salary >= 5000;
--條件2
UPDATE Personnel
SET salary = salary * 1.15
WHERE salary >= 2000 AND salary < 4600;

但是事情沒有想象得那么簡單,假設有個人工資5000塊。首先,按照條件1,工資減少10%,變成工資4500。接下來運行第二個SQL時候,因為這個人的工資是4500在2000到4600的范圍之內, 需增加15%,最后這個人的工資結果是5175,不但沒有減少,反而增加了。如果要是反過來執行,那么工資4600的人相反會變成減少工資。暫且不管這個規章是多么荒誕,如果想要一個SQL 語句實現這個功能的話,我們需要用到Case函數。代碼如下:
UPDATE Personnel
SET salary = CASE WHEN salary >= 5000
             THEN salary * 0.9
WHEN salary >= 2000 AND salary < 4600
THEN salary * 1.15
ELSE salary END;

這里要注意一點,最后一行的ELSE salary是必需的,要是沒有這行,不符合這兩個條件的人的工資將會被寫成NUll,那可就大事不妙了。在Case函數中Else部分的默認值是NULL,這點是需要注意的地方。
這種方法還可以在很多地方使用,比如說變更主鍵這種累活。
一般情況下,要想把兩條數據的Primary key,a和b交換,需要經過臨時存儲,拷貝,讀回數據的三個過程,要是使用Case函數的話,一切都變得簡單多了。
p_key col_1 col_2
a 1 張三
b 2 李四
c 3 王五


假設有如上數據,需要把主鍵ab相互交換。用Case函數來實現的話,代碼如下
UPDATE SomeTable
SET p_key = CASE WHEN p_key = 'a'
THEN 'b'
WHEN p_key = 'b'
THEN 'a'
ELSE p_key END
WHERE p_key IN ('a', 'b');

同樣的也可以交換兩個Unique key。需要注意的是,如果有需要交換主鍵的情況發生,多半是當初對這個表的設計進行得不夠到位,建議檢查表的設計是否妥當。

五,兩個表數據是否一致的檢查。

Case函數不同于DECODE函數。在Case函數中,可以使用BETWEEN,LIKE,IS NULL,IN,EXISTS等等。比如說使用IN,EXISTS,可以進行子查詢,從而 實現更多的功能。
下面具個例子來說明,有兩個表,tbl_A,tbl_B,兩個表中都有keyCol列。現在我們對兩個表進行比較,tbl_A中的keyCol列的數據如果在tbl_B的keyCol列的數據中可以找到, 返回結果'Matched',如果沒有找到,返回結果'Unmatched'。
要實現下面這個功能,可以使用下面兩條語句
--使用IN的時候
SELECT keyCol,
CASE WHEN keyCol IN ( SELECT keyCol FROM tbl_B )
THEN 'Matched'
ELSE 'Unmatched' END Label
FROM tbl_A;
--使用EXISTS的時候
SELECT keyCol,
CASE WHEN EXISTS ( SELECT * FROM tbl_B
WHERE tbl_A.keyCol = tbl_B.keyCol )
THEN 'Matched'
ELSE 'Unmatched' END Label
FROM tbl_A;

使用IN和EXISTS的結果是相同的。也可以使用NOT IN和NOT EXISTS,但是這個時候要注意NULL的情況。

六,在Case函數中使用合計函數

假設有下面一個表
學號(std_id) 課程ID(class_id) 課程名(class_name) 主修flag(main_class_flg)
100 1 經濟學 Y
100 2 歷史學 N
200 2 歷史學 N
200 3 考古學 Y
200 4 計算機 N
300 4 計算機 N
400 5 化學 N
500 6 數學 N

有的學生選擇了同時修幾門課程(100,200)也有的學生只選擇了一門課程(300,400,500)。選修多門課程的學生,要選擇一門課程作為主修,主修flag里面寫入 Y。只選擇一門課程的學生,主修flag為N(實際上要是寫入Y的話,就沒有下面的麻煩事了,為了舉例子,還請多多包含)。
現在我們要按照下面兩個條件對這個表進行查詢
  1. 只選修一門課程的人,返回那門課程的ID
  2. 選修多門課程的人,返回所選的主課程ID

簡單的想法就是,執行兩條不同的SQL語句進行查詢。
條件1
--條件1:只選擇了一門課程的學生
SELECT std_id, MAX(class_id) AS main_class
FROM Studentclass
GROUP BY std_id
HAVING COUNT(*) = 1;

執行結果1
STD_ID   MAIN_class
------   ----------
300      4
400      5
500      6

條件2
--條件2:選擇多門課程的學生
SELECT std_id, class_id AS main_class
FROM Studentclass
WHERE main_class_flg = 'Y' ;

執行結果2
STD_ID  MAIN_class
------  ----------
100     1
200     3

如果使用Case函數,我們只要一條SQL語句就可以解決問題,具體如下所示
SELECT  std_id,
CASE WHEN COUNT(*) = 1  --只選擇一門課程的學生的情況
THEN MAX(class_id)
ELSE MAX(CASE WHEN main_class_flg = 'Y'
THEN class_id
ELSE NULL END
)
END AS main_class
FROM Studentclass
GROUP BY std_id;

運行結果
STD_ID   MAIN_class
------   ----------
100      1
200      3
300      4
400      5
500      6

通過在Case函數中嵌套Case函數,在合計函數中使用Case函數等方法,我們可以輕松的解決這個問題。使用Case函數給我們帶來了更大的自由度。
最后提醒一下使用Case函數的新手注意不要犯下面的錯誤
CASE col_1
WHEN 1        THEN 'Right'
WHEN NULL  THEN 'Wrong'
END

在這個語句中When Null這一行總是返回unknown,所以永遠不會出現Wrong的情況。因為這句可以替換成WHEN col_1 = NULL,這是一個錯誤的用法,這個時候我們應該選擇用WHEN col_1 IS NULL。

周銳 2008-09-24 11:29 發表評論
]]>
SQL中Case的使用方法(上篇)(轉載)http://www.aygfsteel.com/rain1102/archive/2008/09/24/230834.html周銳周銳Wed, 24 Sep 2008 03:20:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/09/24/230834.htmlhttp://www.aygfsteel.com/rain1102/comments/230834.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/09/24/230834.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/230834.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/230834.htmlCase具有兩種格式。簡單Case函數和Case搜索函數。
--簡單Case函數
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
--Case搜索函數
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END

這兩種方式,可以實現相同的功能。簡單Case函數的寫法相對比較簡潔,但是和Case搜索函數相比,功能方面會有些限制,比如寫判斷式。
還有一個需要注意的問題,Case函數只返回第一個符合條件的值,剩下的Case部分將會被自動忽略。
--比如說,下面這段SQL,你永遠無法得到“第二類”這個結果
CASE WHEN col_1 IN ( 'a', 'b') THEN '第一類'
WHEN col_1 IN ('a')       THEN '第二類'
ELSE'其他' END

下面我們來看一下,使用Case函數都能做些什么事情。

一,已知數據按照另外一種方式進行分組,分析。

有如下數據:(為了看得更清楚,我并沒有使用國家代碼,而是直接用國家名作為Primary Key)
國家(country) 人口(population)
中國 600
美國 100
加拿大 100
英國 200
法國 300
日本 250
德國 200
墨西哥 50
印度 250

根據這個國家人口數據,統計亞洲和北美洲的人口數量。應該得到下面這個結果。
人口
亞洲 1100
北美洲 250
其他 700

想要解決這個問題,你會怎么做?生成一個帶有洲Code的View,是一個解決方法,但是這樣很難動態的改變統計的方式。
如果使用Case函數,SQL代碼如下:
SELECT  SUM(population),
CASE country
WHEN '中國'     THEN '亞洲'
WHEN '印度'     THEN '亞洲'
WHEN '日本'     THEN '亞洲'
WHEN '美國'     THEN '北美洲'
WHEN '加拿大'  THEN '北美洲'
WHEN '墨西哥'  THEN '北美洲'
ELSE '其他' END
FROM    Table_A
GROUP BY CASE country
WHEN '中國'     THEN '亞洲'
WHEN '印度'     THEN '亞洲'
WHEN '日本'     THEN '亞洲'
WHEN '美國'     THEN '北美洲'
WHEN '加拿大'  THEN '北美洲'
WHEN '墨西哥'  THEN '北美洲'
ELSE '其他' END;

同樣的,我們也可以用這個方法來判斷工資的等級,并統計每一等級的人數。SQL代碼如下;
SELECT
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600  THEN '2'
WHEN salary > 600 AND salary <= 800  THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END salary_class,
COUNT(*)
FROM    Table_A
GROUP BY
CASE WHEN salary <= 500 THEN '1'
WHEN salary > 500 AND salary <= 600  THEN '2'
WHEN salary > 600 AND salary <= 800  THEN '3'
WHEN salary > 800 AND salary <= 1000 THEN '4'
ELSE NULL END;

二,用一個SQL語句完成不同條件的分組。

有如下數據
國家(country) 性別(sex) 人口(population)
中國 1 340
中國 2 260
美國 1 45
美國 2 55
加拿大 1 51
加拿大 2 49
英國 1 40
英國 2 60

按照國家和性別進行分組,得出結果如下
國家
中國 340 260
美國 45 55
加拿大 51 49
英國 40 60

普通情況下,用UNION也可以實現用一條語句進行查詢。但是那樣增加消耗(兩個Select部分),而且SQL語句會比較長。
下面是一個是用Case函數來完成這個功能的例子
SELECT country,
SUM( CASE WHEN sex = '1' THEN
population ELSE 0 END),  --男性人口
SUM( CASE WHEN sex = '2' THEN
population ELSE 0 END)   --女性人口
FROM  Table_A
GROUP BY country;

這樣我們使用Select,完成對二維表的輸出形式,充分顯示了Case函數的強大。

三,在Check中使用Case函數。

在Check中使用Case函數在很多情況下都是非常不錯的解決方法。可能有很多人根本就不用Check,那么我建議你在看過下面的例子之后也嘗試一下在SQL中使用Check。
下面我們來舉個例子
公司A,這個公司有個規定,女職員的工資必須高于1000塊。如果用Check和Case來表現的話,如下所示
CONSTRAINT check_salary CHECK
( CASE WHEN sex = '2'
THEN CASE WHEN salary > 1000
THEN 1 ELSE 0 END
ELSE 1 END = 1 )

如果單純使用Check,如下所示
CONSTRAINT check_salary CHECK
( sex = '2' AND salary > 1000 )

女職員的條件倒是符合了,男職員就無法輸入了。

USE pubs
GO
SELECT
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END AS Range,
Title
FROM titles
GROUP BY
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END,
Title
ORDER BY
CASE
WHEN price IS NULL THEN 'Unpriced'
WHEN price < 10 THEN 'Bargain'
WHEN price BETWEEN 10 and 20 THEN 'Average'
ELSE 'Gift to impress relatives'
END,
Title
GO



周銳 2008-09-24 11:20 發表評論
]]>
刪除重復記錄http://www.aygfsteel.com/rain1102/archive/2008/09/04/227080.html周銳周銳Thu, 04 Sep 2008 14:52:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/09/04/227080.htmlhttp://www.aygfsteel.com/rain1102/comments/227080.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/09/04/227080.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/227080.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/227080.html問題
從表中刪除重復記錄.

解決方案
用帶有聚集函數的子查詢, 例如MIN, 任意選擇保留的ID(本例中只保留每組中ID號最小的記錄):

    delete from dept 
        where id not in (select min(id) 
                                    from dept 
                                group by name)



周銳 2008-09-04 22:52 發表評論
]]>
復制表定義http://www.aygfsteel.com/rain1102/archive/2008/09/04/227075.html周銳周銳Thu, 04 Sep 2008 14:34:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/09/04/227075.htmlhttp://www.aygfsteel.com/rain1102/comments/227075.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/09/04/227075.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/227075.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/227075.html問題
要創建新表, 該表與已有表的列設置相同. 例如, 想要一個dept表的副本, 名未dept_2, 淡只是想復制表結構而不想復制源表中的記錄.

解決方案
DB2
使用帶有like子句的create table命令:
    create table dept_2 like dept

Oracle, MySQL 和 PostgreSQL
在create table命令中, 使用一個不返回任何行的子查詢:
    create table dept_2
    as
    select * from dept where 1=0

SQL Server
使用帶有不返回任何行的查詢和into子句:
    select * into dept_2 from dept where 1=0

周銳 2008-09-04 22:34 發表評論
]]>
SQL查詢按照子串排序http://www.aygfsteel.com/rain1102/archive/2008/07/16/215298.html周銳周銳Wed, 16 Jul 2008 12:09:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/07/16/215298.htmlhttp://www.aygfsteel.com/rain1102/comments/215298.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/07/16/215298.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/215298.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/215298.html 在DB2, MySQL, Oracle和PostgreSQL中, order by子句中使用substr函數:
    select ename, job from emp order by substr(job, length(job)-2)
在SQL Server中, order by子句中使用substring函數:
    select ename, job from emp order by substring(job, len(job)-2, 2)


周銳 2008-07-16 20:09 發表評論
]]>
限制返回的行數和從表中隨機返回n條記錄http://www.aygfsteel.com/rain1102/archive/2008/07/15/215062.html周銳周銳Tue, 15 Jul 2008 12:50:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/07/15/215062.htmlhttp://www.aygfsteel.com/rain1102/comments/215062.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/07/15/215062.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/215062.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/215062.html在DB2中, 使用FETCH FIRST子句限制返回行數:
    select * from emp fetch first 5 rows only
使用RAND與ORDER BY和FETCH FIRST來獲取隨機條數
    select * from emp order by rand() fetch first 5 rows only

在MySQL和PostgreSQL中, 使用LIMIT:
    select * from emp limit 5
MySQL中獲取隨機行數:
     select * from emp order by rand() limit 5
PostgreSQL中獲取隨機行數:
     select * from emp order by random() limit 5

在Oracle中, 在WHERE子句中通過使用ROWNUM來限制行數:
    select * from emp where rownum <= 5
    
    select *
            from (
                select ename, job from emp order by dbms_random.value()
            )
    where rownum <= 5
在SQL Server中, 使用TOP來限制返回行數:
    select top 5 * from emp
    
    select top 5 ename, job from emp order by newid()



周銳 2008-07-15 20:50 發表評論
]]>
SQL中連接列值和在SELECT語句中使用條件邏輯http://www.aygfsteel.com/rain1102/archive/2008/07/14/214821.html周銳周銳Mon, 14 Jul 2008 13:16:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/07/14/214821.htmlhttp://www.aygfsteel.com/rain1102/comments/214821.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/07/14/214821.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/214821.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/214821.html 使用concat函數連接來自多個列的數值. 在DB2, Oracle和PostgreSQL中,"||"是concat函數的簡寫方式,"+"是SQL Server中的簡寫方式.
select name||' is a '||type as msg from animal where ...
select name+' is a '+type as msg from animal where...
select concat(name, ' is a ', type) as msg from animal where ...

2.在SELECT語句中使用條件邏輯
case表達式可以針對查詢的返回值執行條件邏輯. 可以給case表達式取別名, 使結果集更易讀. else子句是可選的, 如果沒有使用else, 對于不滿足判斷條件的行, case表達式會返回NULL.
select ename, sal,
   case when sal<=2000 then 'UNDERPAID'
   case when sal>=4000 then 'OVERPAID'
          else 'OK'
   end as status
from emp

周銳 2008-07-14 21:16 發表評論
]]>
維護SQL Server數據庫的一些常用SQL(轉)http://www.aygfsteel.com/rain1102/archive/2008/05/13/200246.html周銳周銳Tue, 13 May 2008 09:15:00 GMThttp://www.aygfsteel.com/rain1102/archive/2008/05/13/200246.htmlhttp://www.aygfsteel.com/rain1102/comments/200246.htmlhttp://www.aygfsteel.com/rain1102/archive/2008/05/13/200246.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/200246.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/200246.html1.如何創建數據庫

CREATE DATABASE student

2.如何刪除數據庫

DROP DATABASE student

3.如何備份數據庫到磁盤文件

BACKUP DATABASE student to disk=´c:\1234.bak´

4.如何從磁盤文件還原數據庫

RESTORE DATABASE studnet FROM DISK = ´c:\1234.bak´

5.怎樣創建表?

CREATE TABLE Students (
    ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
    StudentID char (4) NOT NULL ,
    Name char (10) NOT NULL ,
    Age int NULL ,
    Birthday datetime NULL,
    CONSTRAINT PK_Students PRIMARY KEY (StudentID)  --設置主鍵
)

CREATE TABLE Subjects (
    ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
    ClassID char (4) NOT NULL ,
    ClassName char (10) NOT NULL,
    CONSTRAINT PK_Subjects PRIMARY KEY (ClassID)    --設置主鍵
)

CREATE TABLE Scores (
    ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
    StudentID char (4) NOT NULL ,
    ClassID char (4) NOT NULL ,
    Score float NOT NULL,
    CONSTRAINT FK_Scores_Students FOREIGN KEY (StudentID) REFERENCES Students(StudentID), --設置外鍵
    CONSTRAINT FK_Scores_Subjects FOREIGN KEY (ClassID) REFERENCES Subjects(ClassID), --設置外鍵
    CONSTRAINT PK_Scores PRIMARY KEY (StudentID,ClassID) --設置主鍵
)

6.怎樣刪除表?

DROP TABLE Students

7.怎樣創建視圖?

CREATE VIEW s_s_s
AS
SELECT Students.Name, Subjects.ClassName, Scores.Score
FROM Scores INNER JOIN
      Students ON Scores.StudentID = Students.StudentID INNER JOIN
      Subjects ON Scores.ClassID = Subjects.ClassID


8.怎樣刪除視圖?

DROP VIEW s_s_s

9.如何創建存儲過程?

CREATE PROCEDURE GetStudent
@age INT,
@birthday DATETIME
AS
SELECT *
FROM students
WHERE Age = @age AND Birthday = @birthday
GO

10.如何刪除存儲過程?

DROP PROCEDURE GetStudent

11.如何創建觸發器?

CREATE TRIGGER reminder
ON Students
FOR INSERT, UPDATE, DELETE
AS
   EXEC master..xp_sendmail ´MaryM´,
      ´Don´´t forget to print a report for the distributors.´
GO

12.如何刪除觸發器?

DROP TRIGGER reminder

13.如何創建索引?

CREATE UNIQUE INDEX IX_Students ON Students (Name)

14.如何刪除索引?

DROP INDEX Students.IX_Students

15.怎樣給表添加字段?

ALTER TABLE Students ADD Address varchar (50) NULL

16.怎樣刪除表中某個字段?

ALTER TABLE Students DROP COLUMN Address

17.如何設置列的標識屬性?

沒找到辦法

18.如何去掉列的標識屬性?

沒有找到好的方法,只能是先添加一列,然后把標識列的值更新到新加入的列,刪除標識列,再用與標識列相同的名字類型添加一列,用前面加入的列更新該列.如果該標識列是其他表的外鍵,還要先刪除外鍵約束,很麻煩.誰有好的辦法,還請告訴我.

19.如何重設標識列的標識種子?

DBCC CHECKIDENT (Student, RESEED, 1)

20.怎樣給表加上主鍵?

ALTER TABLE Scores ADD CONSTRAINT PK_Scores PRIMARY KEY (StudentID,ClassID)

21.怎樣刪除表的主鍵?

ALTER TABLE Scores DROP CONSTRAINT PK_Scores

22.怎樣給表添加一個外鍵?

ALTER TABLE Scores ADD CONSTRAINT FK_Scores_Students FOREIGN KEY (StudentID) REFERENCES Students (StudentID) ON DELETE CASCADE

23.怎樣刪除表的一個外鍵?

ALTER TABLE Scores DROP CONSTRAINT FK_Scores_Students

24.怎樣給字段加上CHECK約束?

ALTER TABLE Students ADD CONSTRAINT CK_Students CHECK (Age > 0)

25.怎樣去掉字段上的CHECK約束?

ALTER TABLE Students DROP CONSTRAINT CK_Students

26.怎樣給字段設置默認值?

ALTER TABLE Students ADD CONSTRAINT DF_Students_Age DEFAULT (18) FOR Age

27.怎樣移去字段的默認值?

ALTER TABLE Students DROP CONSTRAINT DF_Students_Age

28.修改字段的類型及非空約束

ALTER TABLE Students ALTER COLUMN Age char (10) null
ALTER TABLE Students ALTER COLUMN Age int not null



周銳 2008-05-13 17:15 發表評論
]]>
MySQL下使用Hibernate的Query中setMaxResults方法出現錯誤http://www.aygfsteel.com/rain1102/archive/2007/12/27/170767.html周銳周銳Wed, 26 Dec 2007 16:47:00 GMThttp://www.aygfsteel.com/rain1102/archive/2007/12/27/170767.htmlhttp://www.aygfsteel.com/rain1102/comments/170767.htmlhttp://www.aygfsteel.com/rain1102/archive/2007/12/27/170767.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/170767.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/170767.html System Runtime Error: JDBC exception on Hibernate data access; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
這是因為MySQL不支持top,而是使用了limit!
目前還沒找到解決辦法,不知道為什么Hibernate搞出這玩意,干嗎不轉換一下,還是bug呢!暈!

終于解決了,不是人家的錯誤,而是我自己弄錯了。方言干錯了!失敗!

周銳 2007-12-27 00:47 發表評論
]]>
mysql 導出所有表和所有數據http://www.aygfsteel.com/rain1102/archive/2007/11/23/162575.html周銳周銳Fri, 23 Nov 2007 03:22:00 GMThttp://www.aygfsteel.com/rain1102/archive/2007/11/23/162575.htmlhttp://www.aygfsteel.com/rain1102/comments/162575.htmlhttp://www.aygfsteel.com/rain1102/archive/2007/11/23/162575.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/162575.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/162575.htmlmysqldump -u root -p --default-character-set=gbk jbpmtest [table1,table2,...] > c:\jbpmtestdump.sql


mysqldump -u root -p --default-character-set=gbk testAcegi > c:\testAcegiDump.sql

mysqldump -u root -p --default-character-set=gbk knightsoft > c:\knightsoft.sql



周銳 2007-11-23 11:22 發表評論
]]>
判斷sql執行所花的時間(精度為毫秒)http://www.aygfsteel.com/rain1102/archive/2007/09/28/149059.html周銳周銳Fri, 28 Sep 2007 05:02:00 GMThttp://www.aygfsteel.com/rain1102/archive/2007/09/28/149059.htmlhttp://www.aygfsteel.com/rain1102/comments/149059.htmlhttp://www.aygfsteel.com/rain1102/archive/2007/09/28/149059.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/149059.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/149059.htmlDECLARE @begin datetime
DECLARE @chaju bigint
DECLARE @end datetime
SET @begin=getdate()

要執行的sql語句......

SET @end=getdate()       
SELECT @chaju = datediff(Millisecond, @begin@end)
PRINT @chaju 

周銳 2007-09-28 13:02 發表評論
]]>
使用Python操作MySQLhttp://www.aygfsteel.com/rain1102/archive/2007/09/25/148037.html周銳周銳Tue, 25 Sep 2007 05:22:00 GMThttp://www.aygfsteel.com/rain1102/archive/2007/09/25/148037.htmlhttp://www.aygfsteel.com/rain1102/comments/148037.htmlhttp://www.aygfsteel.com/rain1102/archive/2007/09/25/148037.html#Feedback0http://www.aygfsteel.com/rain1102/comments/commentRss/148037.htmlhttp://www.aygfsteel.com/rain1102/services/trackbacks/148037.html

1.   使用
    import MySQLdb
1.1.   連接
    conn =   MySQLdb.Connection(host, user, password, dbname)
1.2.   選擇數據庫,如果上面沒有指定數據庫,則使用此方法指定!
    conn.select_db(’database name’)
1.3.   獲得cursor
    cur =   conn.cursor()
1.4.   cursor位置設定
    cur.scroll(int, mode)
    mode可為相對位置或者絕對位置,分別為relative和absolute。
1.5.   select
    cur.execute(‘select clause’)
    例如
    cur.execute(‘select * from mytable’)

    row = cur.fetchall()
    或者:
    row1 = cur.fetchone()
1.6.   insert
    cur.execute(‘inset clause’)
    例如
    cur.execute("insert into user (Name, Password) values ('maggie','12345')")
    conn.commit()

1.7.   update
    cur.execute(‘update  clause’)
    例如
    cur.execute("update user set Name = 'eric chau' where id = 1")
    conn.commit()

1.8.   delete
    cur.execute(‘delete  clause’)
    例如
    cur.execute("delete from user where id = 1")
    conn.commit()


完整代碼:

from MySQLdb import Connect

def conn():
    #conn = Connect('localhost','root','root')
    #conn.select_db('eric')
    conn = Connect('localhost','root','root','eric')
    cur = conn.cursor()
    cur.execute('select * from user')
    cur.scroll(0)
    row1 = cur.fetchone()
    print 'id:', row1[0]
    print 'name:', row1[1]
    print 'password:', row1[2]
    #cur.execute("insert into user (Name, Password) values ('maggie','12345')")
    #cur.execute("update user set Name = 'eric chau' where id = 1")
    cur.execute("delete from user where id = 11")
    conn.commit()
if __name__=='__main__':
    conn()



周銳 2007-09-25 13:22 發表評論
]]>
主站蜘蛛池模板: 嘉禾县| 凌海市| 堆龙德庆县| 盱眙县| 哈尔滨市| 分宜县| 涞源县| 河南省| 兴义市| 海门市| 许昌市| 惠来县| 巧家县| 临泽县| 泗阳县| 明溪县| 正阳县| 谷城县| 阿城市| 武平县| 彰化县| 晋宁县| 济源市| 河津市| 民丰县| 广水市| 方城县| 二手房| 嵩明县| 和林格尔县| 时尚| 监利县| 山丹县| 凌源市| 九寨沟县| 通化市| 云阳县| 武山县| 肃宁县| 新邵县| 郸城县|