Sql server SQL Server 2008中类似阵列的功能
我想根据某些条件读取Sql server SQL Server 2008中类似阵列的功能,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我想根据某些条件读取EMP表中的EmpID。对于每个EmpID,我需要在另一个表中执行一些操作。如何一次读取EmpID的单个值 通常,您应该避免使用SQL中的过程代码,但如果确实需要,请使用游标: UPDATE otherTable... WHERE table2.EmpID IN (SELECT EMP.EmpID FROM EMP WHERE ...) DECLARE myCursor CURSOR FAST_FORWARD FOR SELECT --your SQL qu
EMP
表中的EmpID
。对于每个EmpID
,我需要在另一个表中执行一些操作。如何一次读取EmpID
的单个值
通常,您应该避免使用SQL中的过程代码,但如果确实需要,请使用游标:
UPDATE otherTable...
WHERE table2.EmpID IN (SELECT EMP.EmpID FROM EMP WHERE ...)
DECLARE myCursor CURSOR FAST_FORWARD
FOR
SELECT --your SQL query, a regular SQL query.
field1,
field2
FROM
table
OPEN myCursor;
FETCH NEXT FROM myCursor
INTO
@var1, --must be pre-declared, of the same types as field1
@var2
WHILE (@@FETCH_STATUS = 0)
BEGIN
--your code use @var1, @var2. Perform queries, do whatever you like.
--It will loop through every row fetched by the query in the beginning of the code, and perform this.
FETCH NEXT FROM myCursor --do this exactly as before the WHILE loop
INTO
@var1,
@var2
END
CLOSE myCursor
通常,您应该避免使用SQL中的过程代码,但如果确实需要,请使用游标:
DECLARE myCursor CURSOR FAST_FORWARD
FOR
SELECT --your SQL query, a regular SQL query.
field1,
field2
FROM
table
OPEN myCursor;
FETCH NEXT FROM myCursor
INTO
@var1, --must be pre-declared, of the same types as field1
@var2
WHILE (@@FETCH_STATUS = 0)
BEGIN
--your code use @var1, @var2. Perform queries, do whatever you like.
--It will loop through every row fetched by the query in the beginning of the code, and perform this.
FETCH NEXT FROM myCursor --do this exactly as before the WHILE loop
INTO
@var1,
@var2
END
CLOSE myCursor
对SQL逻辑使用基于集合的方法始终是首选方法。从这个意义上说,丹丹的回答是可以接受的。 或者,您可以使用SQL游标。虽然资源很重,但它们允许您迭代一个集合,并在每一行上应用一些逻辑
DECLARE @EMPID char(11)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT EmpID
FROM EMP
WHERE*some_子句*
OPEN c1
FETCH NEXT FROM c1
INTO @EMPID
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @EMPID
FETCH NEXT FROM c1
INTO @EMPID
END
CLOSE c1
DEALLOCATE c1
对SQL逻辑使用基于集合的方法始终是首选方法。从这个意义上说,丹丹的回答是可以接受的。 或者,您可以使用SQL游标。虽然资源很重,但它们允许您迭代一个集合,并在每一行上应用一些逻辑
DECLARE @EMPID char(11)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT EmpID
FROM EMP
WHERE*some_子句*
OPEN c1
FETCH NEXT FROM c1
INTO @EMPID
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @EMPID
FETCH NEXT FROM c1
INTO @EMPID
END
CLOSE c1
DEALLOCATE c1
在from之后,T-SQL允许您在UPDATE
语句的from
子句中进行连接(我不记得这是不是ANSI)。乙二醇
在from之后,T-SQL允许您在UPDATE
语句的from
子句中进行连接(我不记得这是不是ANSI)。乙二醇
尽量避免循环,处理数据集。 您可以一次插入、更新、删除多行。以下是插入多行的示例:
INSERT INTO YourTable
(col1, col2, col3, col4)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
您甚至可以在一条语句中插入多个表:
INSERT INTO YourTable
(col1, col2, col3, col4)
OUTPUT INSERTED.PK, Inserted.Col2
INTO OtherTable (ColA, ColB)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
当观察一个循环时,看看它在循环中做了什么。如果只是插入/删除/更新,请重新写入以使用单个命令。如果存在IFs,请查看它们是否可以是CASE语句或插入/删除/更新的WHERE条件。如果是,请删除循环并使用set命令
我采用了循环,用基于集合的命令替换它们,并将执行时间从几分钟缩短到几秒钟。我使用了包含许多嵌套循环和过程调用的过程,并保留了循环(不可能只使用插入/删除/更新),但我删除了光标,并且看到了更少的锁定/阻塞和大量性能提升。这里有两种比游标循环更好的循环方法
如果必须循环,请在集合上执行以下操作:
--this looks up each row for every iteration
DECLARE @msg VARCHAR(250)
DECLARE @hostname sysname
--first select of currsor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
WHILE @hostname is not null
BEGIN
--just some example of some odd task that requires a loop
set @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(@hostname) + ' '
+ 'testing "'
print @msg
--EXEC (@msg) --<<will not actually send the messages
--next select of cursor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
and hostname > @hostname
END
——这将为每次迭代查找每一行
声明@msg VARCHAR(250)
声明@hostname sysname
--电流自由循环的首次选择
选择@hostname=min(RTRIM(主机名))
来自master.dbo.sysprocesss(NOLOCK)
其中主机名为“”
而@hostname不为空
开始
--只是一些需要循环的奇怪任务的示例
将@msg='exec master.dbo.xp\u cmdshell设置为“净发送”
+RTRIM(@hostname)+”
+“测试”
打印@msg
--EXEC(@msg)--尝试从不循环,处理数据集。
您可以一次插入、更新、删除多行。以下是插入多行的示例:
INSERT INTO YourTable
(col1, col2, col3, col4)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
您甚至可以在一条语句中插入多个表:
INSERT INTO YourTable
(col1, col2, col3, col4)
OUTPUT INSERTED.PK, Inserted.Col2
INTO OtherTable (ColA, ColB)
SELECT
cola, colb+Colz, colc, @X
FROM ....
LEFT OUTER JOIN ...
WHERE...
当观察一个循环时,看看它在循环中做了什么。如果只是插入/删除/更新,请重新写入以使用单个命令。如果存在IFs,请查看它们是否可以是CASE语句或插入/删除/更新的WHERE条件。如果是,请删除循环并使用set命令
我采用了循环,用基于集合的命令替换它们,并将执行时间从几分钟缩短到几秒钟。我使用了包含许多嵌套循环和过程调用的过程,并保留了循环(不可能只使用插入/删除/更新),但我删除了光标,并且看到了更少的锁定/阻塞和大量性能提升。这里有两种比游标循环更好的循环方法
如果必须循环,请在集合上执行以下操作:
--this looks up each row for every iteration
DECLARE @msg VARCHAR(250)
DECLARE @hostname sysname
--first select of currsor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
WHILE @hostname is not null
BEGIN
--just some example of some odd task that requires a loop
set @msg='exec master.dbo.xp_cmdshell "net send '
+ RTRIM(@hostname) + ' '
+ 'testing "'
print @msg
--EXEC (@msg) --<<will not actually send the messages
--next select of cursor free loop
SELECT @hostname= min(RTRIM(hostname))
FROM master.dbo.sysprocesses (NOLOCK)
WHERE hostname <> ''
and hostname > @hostname
END
——这将为每次迭代查找每一行
声明@msg VARCHAR(250)
声明@hostname sysname
--电流自由循环的首次选择
选择@hostname=min(RTRIM(主机名))
来自master.dbo.sysprocesss(NOLOCK)
其中主机名为“”
而@hostname不为空
开始
--只是一些需要循环的奇怪任务的示例
将@msg='exec master.dbo.xp\u cmdshell设置为“净发送”
+RTRIM(@hostname)+”
+“测试”
打印@msg
--EXEC(@msg)--你能解释一下“某些操作”吗?每个答案旁边都有两个箭头。如果你喜欢这个答案,如果它有点帮助,那么点击向上按钮(向上投票)是一个很好的做法,如果答案完全错了,你可以向下投票,尽管人们不喜欢它,你也会失去声誉点数。如果您的问题得到了正确的答案,您必须将其标记为正确(答案旁边箭头下方的绿色复选标记)。这是一种“责任”,伴随着提出问题的权利而来。如果你不这样做,人们在将来会不那么愿意帮助你。你能解释一下“一些操作”吗?每个答案旁边都有两个箭头。如果你喜欢这个答案,如果它有点帮助,那么点击向上按钮(向上投票)是一个很好的做法,如果答案完全错了,你可以向下投票,尽管人们不喜欢它,你也会失去声誉点数。如果您的问题得到了正确的答案,您必须将其标记为正确(答案旁边箭头下方的绿色复选标记)。这是一种“责任”,伴随着提出问题的权利而来。如果你不这样做,人们在将来会不那么热心地帮助你。非常感谢你的回应。实际上我是在写过程,我没有实现游标。通过“过程”我指的是迭代代码,在这里你提供步骤,你把任务分解成最小的部分,并定义指令序列。与之相反的是声明性语法,即SQL(以及更多),在这里,您可以声明您需要的内容,而不提供特定的