sql遍歷表
㈠ sql="select * from 數據表 where 變數 in(欄位名)"
用charindex函數:
a1="1"
sql="select * from 數據表 where '"&a1&"' in(欄位名)"
成
a1="1"
select * from 數據表 where
欄位名 In
(
select 欄位名 From 數據表 where charindex(a1,欄位名)>0
)
In語句的用法樓主需要熟悉一下,否則你不能熟練正確地運用In語句
㈡ 我寫了一個pl/sql,主要是用游標遍歷一張表.
1.檢查一下游標C1中查詢語句的執行計劃,看看是不是耗時很多。10萬數據並不多,而且你做了函數索引。所以我滾納滑猜這個不是問大臘題產生的原因;
2.檢查一下你的兩層循環到底有多少次,是不茄薯是次數過多。目測不會超過10萬吧。所以應該也不是問題關鍵;
*.以上兩點可以通過使用plsql developer工具debug該過程時,點擊create profiler report,然後執行,再從debug界面的profiler分頁查看。
3.你的過程中 update cyd 和 fhz,執行過程的時候,有沒有什麼其他程序再多兩個表做update,有沒有鎖表。cup使用率是否高;
4.通常不要在查詢a表的循環中對a表update。你這里查詢Cyd內部就對Cyd進行了update,這樣有問題。我曾經遇到過,程序會鎖住。
*.對於你的程序,給你個建議,把一下這段代碼寫成一個function,在由表中查尋結果中直接調用:
FOR i IN 1 .. Lengthb(Yw_Old) LOOP
Tmp := Substr(Yw_Old, i, 1);
IF (Tmp = 'A') THEN
Yw_New := Yw_New || 'B3';
ELSIF (Tmp = 'B') THEN
Yw_New := Yw_New || 'B3';
ELSIF (Tmp = 'C') THEN
Yw_New := Yw_New || 'C1';
ELSIF (Tmp = 'D') THEN
Yw_New := Yw_New || 'D1';
END IF;
END LOOP;
*.假設function叫做fun_pack,游標改成這樣:
CURSOR C1 IS
SELECT Cyh,
fun_pack(Yw),
Pzyw,
Djyw
FROM Cyd
WHERE Substr(Slsj, 1, 4) = Yearc;
㈢ 如何用SQL遍歷整張表
在資料庫開發過程中,我們經常會碰到要遍歷數據表的情形,一提到遍歷表,我們第一印象可能就想到使用游標,使用游標雖然直觀易懂,但是它不符合面向集合操作的原則,而且性能也比面向集合低。當然,從面向集合操作的角度出發,也有兩種方法可以進行遍歷表的操作,總結起來,遍歷表有下面幾種方法。
使用游標
使用表變數
使用臨時表
-- 需求是,新增一列fullname,取值firstname+lastnameALTER TABLE HR.Employees ADD fullname NVARCHAR(30) NULL;GO
1 -- 方法2:使用表變數
2 -- 聲明表變數
3 DECLARE @temp TABLE
4 (
5 empid INT,
6 firstname NVARCHAR(10),
7 lastname NVARCHAR(20)
8 );
9
10 -- 將源表中的數據插入到表變數中
11 INSERT INTO @temp(empid, firstname, lastname )
12 SELECT empid,firstname,lastname FROM HR.Employees
13 ORDER BY empid;
14
15 -- 聲明變數
16 DECLARE
17 @empid AS INT,
18 @firstname AS NVARCHAR(10),
19 @lastname AS NVARCHAR(20);
20
21 WHILE EXISTS(SELECT empid FROM @temp)
22 BEGIN
23 -- 也可以使用top 1
24 SET ROWCOUNT 1
25 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM @temp;
26 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
27 SET ROWCOUNT 0
28
29 DELETE FROM @temp WHERE empid=@empid;
30 END
1 -- 方法3:使用臨時表
2 -- 創建臨時表
3 IF OBJECT_ID('tempdb.dbo.#tempemployees','U') IS NOT NULL DROP TABLE dbo.#tempemployees;
4 GO
5
6 SELECT empid,firstname,lastname
7 INTO dbo.#tempemployees
8 FROM HR.Employees
9 ORDER BY empid;
10
11 --SELECT * FROM dbo.#tempemployees;
12
13 -- 聲明變數
14 DECLARE
15 @empid AS INT,
16 @firstname AS NVARCHAR(10),
17 @lastname AS NVARCHAR(20);
18
19 WHILE EXISTS(SELECT empid FROM dbo.#tempemployees)
20 BEGIN
21 -- 也可以使用top 1
22 SET ROWCOUNT 1
23 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM dbo.#tempemployees;
24 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
25 SET ROWCOUNT 0
26
27 DELETE FROM dbo.#tempemployees WHERE empid=@empid;
28 END
我的需求是:針對HR.Employees表,新增一列fullname,並取值firstname+lastname。
原始效果如下圖。
可以看到,已經達到我們想要的效果了。
使用表變數
因為使用游標存在性能和違背面向集合思想的問題,所以我們有必要用面向集合的思想去找到一種更好的解決方案,下面這種方法是使用表變數的方式實現的,代碼如下。
使用臨時表
臨時表也可以實現表變數的功能,所以我們也可以使用臨時表來實現這個需求,代碼如下。
當然,實現的效果都是一樣的。