将此游标函数替换为 while 循环函数
Replace this cursor function to a while loop function
我创建了这个存储过程,它从我创建的名为 newusers
的 table 中获取参数 username, password, firstname, lastname, DOB, email
,并将它们放入具有字段的相应 table 中提及。我使用这个游标函数来完成它,但他们告诉我游标不是一个好主意,所以我如何用 while 循环函数替换它?
ALTER PROCEDURE [dbo].[Savenewuser]
AS
DECLARE @username VARCHAR(100);
DECLARE @password VARCHAR(100);
DECLARE @firstname VARCHAR(100);
DECLARE @lastname VARCHAR(100);
DECLARE @address VARCHAR(100);
DECLARE @birthdate DATE;
DECLARE @email VARCHAR(100);
BEGIN
DECLARE newuser_cursor CURSOR FOR
SELECT username,
password,
firstname,
lastname,
address,
birthdate,
email
FROM newuser
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO users (username, password)
SELECT @username, @password
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
BEGIN
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO userdetails (first_name, last_name, user_address, dob)
SELECT @firstname, @lastname, @address, @birthdate
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
BEGIN
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO emailbook (email)
SELECT @email
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
DEALLOCATE newuser_cursor
您根本不需要游标。整个事情可以(并且应该 - sql 服务器总是不鼓励对逐行完成的数据集进行操作)作为 INSERT ... SELECT
ALTER PROCEDURE [dbo].[Savenewuser]
AS
BEGIN
INSERT INTO users
(username,
password)
SELECT username,
password
FROM newuser;
INSERT INTO userdetails
(first_name,
last_name,
user_address,
dob)
SELECT firstname,
lastname,
address,
birthdate
FROM newuser;
等等
虽然不太确定您对主键做了什么..
如前所述,始终尝试将一百万条记录作为一百万条记录的单个块来处理,而不是一次拉出一条记录的游标,一百万次
只是为了这个问题,我不建议在任何情况下使用这种方法。
由于您只想使用游标来执行此操作,因此请优化您的查询。
您不需要在每个 insert
命令后打开和关闭光标,因为您将在第一个 fetch
语句中获得记录,然后您可以写入所有 insert
命令一气呵成。然后 close
和 deallocate
光标。
ALTER PROCEDURE [dbo].[Savenewuser]
AS
DECLARE @username VARCHAR(100);
DECLARE @password VARCHAR(100);
DECLARE @firstname VARCHAR(100);
DECLARE @lastname VARCHAR(100);
DECLARE @address VARCHAR(100);
DECLARE @birthdate DATE;
DECLARE @email VARCHAR(100);
BEGIN
DECLARE newuser_cursor CURSOR FOR
SELECT username,
password,
firstname,
lastname,
address,
birthdate,
email
FROM newuser
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO users (username, password)
SELECT @username, @password
INSERT INTO userdetails (first_name, last_name, user_address, dob)
SELECT @firstname, @lastname, @address, @birthdate
INSERT INTO emailbook (email)
SELECT @email
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
DEALLOCATE newuser_cursor
END
正如我在您的代码中看到的那样,您正在拆分列数据并插入到相应的表中。我认为在这种情况下,您仅使用 join 即可实现。
Insert into #users(username,password)
Select username,password from #newuser
Insert into #userdetails(username,firstname, lastname, address, birthdate)
Select u.username, n.firstname, n.lastname, n.address, n.birthdate
from #newuser n join #users u on n.username=u.username
Insert into #emailbook(username,email)
Select u.username,n.email
from #newuser n join #users u on n.username=u.username
我创建了这个存储过程,它从我创建的名为 newusers
的 table 中获取参数 username, password, firstname, lastname, DOB, email
,并将它们放入具有字段的相应 table 中提及。我使用这个游标函数来完成它,但他们告诉我游标不是一个好主意,所以我如何用 while 循环函数替换它?
ALTER PROCEDURE [dbo].[Savenewuser]
AS
DECLARE @username VARCHAR(100);
DECLARE @password VARCHAR(100);
DECLARE @firstname VARCHAR(100);
DECLARE @lastname VARCHAR(100);
DECLARE @address VARCHAR(100);
DECLARE @birthdate DATE;
DECLARE @email VARCHAR(100);
BEGIN
DECLARE newuser_cursor CURSOR FOR
SELECT username,
password,
firstname,
lastname,
address,
birthdate,
email
FROM newuser
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO users (username, password)
SELECT @username, @password
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
BEGIN
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO userdetails (first_name, last_name, user_address, dob)
SELECT @firstname, @lastname, @address, @birthdate
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
BEGIN
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO emailbook (email)
SELECT @email
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
DEALLOCATE newuser_cursor
您根本不需要游标。整个事情可以(并且应该 - sql 服务器总是不鼓励对逐行完成的数据集进行操作)作为 INSERT ... SELECT
ALTER PROCEDURE [dbo].[Savenewuser]
AS
BEGIN
INSERT INTO users
(username,
password)
SELECT username,
password
FROM newuser;
INSERT INTO userdetails
(first_name,
last_name,
user_address,
dob)
SELECT firstname,
lastname,
address,
birthdate
FROM newuser;
等等
虽然不太确定您对主键做了什么..
如前所述,始终尝试将一百万条记录作为一百万条记录的单个块来处理,而不是一次拉出一条记录的游标,一百万次
只是为了这个问题,我不建议在任何情况下使用这种方法。
由于您只想使用游标来执行此操作,因此请优化您的查询。
您不需要在每个 insert
命令后打开和关闭光标,因为您将在第一个 fetch
语句中获得记录,然后您可以写入所有 insert
命令一气呵成。然后 close
和 deallocate
光标。
ALTER PROCEDURE [dbo].[Savenewuser]
AS
DECLARE @username VARCHAR(100);
DECLARE @password VARCHAR(100);
DECLARE @firstname VARCHAR(100);
DECLARE @lastname VARCHAR(100);
DECLARE @address VARCHAR(100);
DECLARE @birthdate DATE;
DECLARE @email VARCHAR(100);
BEGIN
DECLARE newuser_cursor CURSOR FOR
SELECT username,
password,
firstname,
lastname,
address,
birthdate,
email
FROM newuser
OPEN newuser_cursor
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO users (username, password)
SELECT @username, @password
INSERT INTO userdetails (first_name, last_name, user_address, dob)
SELECT @firstname, @lastname, @address, @birthdate
INSERT INTO emailbook (email)
SELECT @email
FETCH next FROM newuser_cursor INTO @username, @password, @firstname,
@lastname, @address, @birthdate, @email
END
CLOSE newuser_cursor
DEALLOCATE newuser_cursor
END
正如我在您的代码中看到的那样,您正在拆分列数据并插入到相应的表中。我认为在这种情况下,您仅使用 join 即可实现。
Insert into #users(username,password)
Select username,password from #newuser
Insert into #userdetails(username,firstname, lastname, address, birthdate)
Select u.username, n.firstname, n.lastname, n.address, n.birthdate
from #newuser n join #users u on n.username=u.username
Insert into #emailbook(username,email)
Select u.username,n.email
from #newuser n join #users u on n.username=u.username