在过去的几年里,我在c#中付出了很多努力并且离开了sql server。 我的sql技能可能会更好。 我知道游标很慢等等......我已经把一个我在工作中遇到相当多的点头示例放在一起。
我需要从一个平面表“Customer”中迁移数据
进入许多表
“CustomerAddress”“CustomerPhone”等。
如果你被分配了这个任务,你怎么能不使用游标呢?
要转换的光标
BEGIN TRANSACTION
DECLARE @CustomerID int,
@Name nvarchar(50),
@Surname nvarchar(50),
@DateOfBirth datetime,
@Address nvarchar(200),
@City nvarchar(50),
@County nvarchar(50),
@Country nvarchar(50),
@HomePhone nvarchar(20)
DECLARE OldCustomerCursor CURSOR FAST_FORWARD
FOR
SELECT CustomerID,Name,Surname,DateOfBirth,Address,City,County,Country,HomePhone
FROM OldCustomer
OPEN OldCustomerCursor
FETCH NEXT FROM OldCustomerCursor INTO @CustomerID,
@Name ,
@Surname ,
@DateOfBirth ,
@Address ,
@City ,
@County ,
@Country ,
@HomePhone
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT [dbo].[Customer] ([CustomerID], [Name], [Surname], [DateOfBirth])
VALUES(@CustomerID,@Name,@Surname,@DateOfBirth)
INSERT [CustomerAddress]([AddressID],[CustomerID],[Country],[Address],[City],[County])
VALUES(@Count,@CustomerID,@County,@Address,@City,@Country)
INSERT [dbo].[CustomerTelephone]([TelephoneID],[CustomerID],[Number])
VALUES(@Count,@CustomerID, @HomePhone)
FETCH NEXT FROM OldCustomerCursor INTO @CustomerID,
@Name ,
@Surname ,
@DateOfBirth ,
@Address ,
@City ,
@County ,
@Country ,
@HomePhone
END
CLOSE OldCustomerCursor
DEALLOCATE OldCustomerCursor
SELECT * FROM Customer
SELECT * FROM CustomerAddress
SELECT * FROM CustomerTelephone
ROLLBACK TRANSACTION
感谢您提供有关如何更换光标的任何建议
答案 0 :(得分:2)
INSERT INTO tablename (column1, column2 ...)
SELECT column1, column2...
FROM mastertable
为每组列和表执行此操作。
答案 1 :(得分:1)
我认为没有理由使用游标,你可以像这样尝试
SELECT CustomerID,Name,Surname,DateOfBirth,Address,City,County,Country,HomePhone
FROM OldCustomer
INSERT [dbo].[Customer] ([CustomerID], [Name], [Surname], [DateOfBirth])
SELCT CustomerID,Name,Surname,DateOfBirth
FROM OldCustomer
INSERT [CustomerAddress]([AddressID],[CustomerID],[Country],[Address],[City],[County])
SELECT Count,CustomerID,County,Address,City,Country
FROM OldCustomer
INSERT [dbo].[CustomerTelephone]([TelephoneID],[CustomerID],[Number])
SELECT Count,CustomerID, HomePhone
FROM OldCustomer
答案 2 :(得分:0)
建议您阅读此内容,了解如何避免使用游标。 http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them
另外,如果系统正在生成GUID,请查看OUTPUT子句以获取GUID(以及自然键,以便您知道要将哪个记录与之关联)。
答案 3 :(得分:0)
我有一个正在进行索赔裁决的存储过程:通过游标查看每个索赔,然后根据索赔类型填充必要的表来处理它。它非常慢 - 需要几个小时才能运行。我通过使用基于集合的SQL处理每组类似的声明来优化它。它跑了几秒钟。
通常,人们认为他们需要游标来代表一系列条件:
DECLARE UserCursor CURSOR
FOR SELECT UserType, UserID FROM Users
OPEN UserCursor
FETCH NEXT whatever
CASE UserType
WHEN 'Employee' THEN do something
WHEN 'Manager' THEN do another thing
WHEN 'Owner' THEN do get coffee
WHEN 'Customer' THEN take money
END
CLOSE CURSOR
或类似的东西。
实际上,你可以这样做:
SELECT UserType, UserID
FROM Users
WHERE UserType = 'Employee'
do something
SELECT UserType, UserID
FROM Users
WHERE UserType = 'Manager'
do another thing
等
这对程序程序员来说看起来更糟糕,但它所以更快,甚至都不好笑。不要考虑基于行的处理,考虑基于集合的处理。这就是数据库的用途。
答案 4 :(得分:0)
您可以使用表变量而不是游标
--declare table variable
declare @tblCustomersVar table
(
CustomerID int,
Name nvarchar(50),
Surname nvarchar(50),
DateOfBirth datetime,
Address nvarchar(200),
City nvarchar(50),
County nvarchar(50),
Country nvarchar(50),
HomePhone nvarchar(20)
)
insert into @tblCustomersVar
SELECT CustomerID,Name,Surname,DateOfBirth,Address,City,County,Country,HomePhone
FROM OldCustomer
--declare @counter variable
declare @counter int
declare @rowCount int
set @counter=1
set @rowCount=(select COUNT(*) from @tblCustomersVar)
while(@counter<=@rowCount)
Begin
--process here
--increment
set @counter=@counter+1
End