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。
原始效果如下图。
可以看到,已经达到我们想要的效果了。
使用表变量
因为使用游标存在性能和违背面向集合思想的问题,所以我们有必要用面向集合的思想去找到一种更好的解决方案,下面这种方法是使用表变量的方式实现的,代码如下。
使用临时表
临时表也可以实现表变量的功能,所以我们也可以使用临时表来实现这个需求,代码如下。
当然,实现的效果都是一样的。