Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server 2008中类似阵列的功能_Sql Server_Sql Server 2008 - Fatal编程技术网

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(以及更多),在这里,您可以声明您需要的内容,而不提供特定的