Как я могу заменить курсор в SQL Server 2008 - PullRequest
0 голосов
/ 02 апреля 2011

В последние годы я приложил много усилий в c # и немного оставил SQL Server. Мои навыки sql могут быть лучше. Я знаю, что курсоры работают медленно и т. Д. Я собрал странный пример, с которым мне, кажется, приходится сталкиваться на работе.

Мне нужно перенести данные из одной плоской таблицы «Клиент»

во многих таблицах

"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

Спасибо за любые предложения, как заменить курсор

Ответы [ 5 ]

2 голосов
/ 02 апреля 2011
INSERT INTO tablename (column1, column2 ...)
SELECT column1, column2...
FROM mastertable

Сделайте это для каждой группы столбцов и таблицы.

1 голос
/ 02 апреля 2011

Я не вижу смысла использовать курсоры, вы можете попробовать это так

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
0 голосов
/ 31 мая 2014

Вы можете использовать табличные переменные вместо курсоров

--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
0 голосов
/ 14 апреля 2011

У меня была хранимая процедура, которая выполняла рассмотрение претензий: просматривая каждую заявку с помощью курсора, а затем обрабатывая ее, заполняя необходимые таблицы в зависимости от типа заявки. Это было ужасно медленно - бегали часами. Я оптимизировал его, обрабатывая каждую группу похожих заявок с использованием 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

и т.д.

Это выглядит хуже для процедурного программиста, но это , поэтому намного быстрее, это даже не смешно. Не думайте об обработке на основе строк, думайте об обработке на основе множеств. Для этого созданы базы данных.

0 голосов
/ 14 апреля 2011

Предлагаю вам прочитать это для идей о том, как избежать курсоров.http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them

Также посмотрите на предложение OUTPUT, чтобы вернуть ваши GUID (и естественные ключи, чтобы вы знали, с какой записью их связать), если они генерируются системой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...