Microsoft SQL Server 2008 курсор - PullRequest
       9

Microsoft SQL Server 2008 курсор

0 голосов
/ 06 сентября 2011

У меня есть #temptable с адресной информацией, которая читается с помощью курсора. Курсор работает отлично. Оператор if в курсоре работает на 100% для первой записи в #table, но для второй записи он всегда возвращает false.

Идея оператора if состоит в том, чтобы проверить значение, которое существует в таблице адресов в БД, а затем, если оно просто получает идентификатор. Если это не так, вставьте строку и получите идентификатор. Автономное утверждение if работает на 100%. В тот момент, когда я добавляю его в курсор, он ломается. Это почти как если бы переменные как-то перезаписывались.

Так что, если в моей #table содержится одна и та же строка, она все равно вставляется дважды в address_table, а не только один раз. Первый раз, когда адрес вставлен, если он не существует, во второй раз идентификатор адреса в таблице должен быть восстановлен

Я вынул операторы print, где я выполняю convert () , и, похоже, это ничего не изменило.

Это отдельное утверждение if.

DECLARE @COMP_NUM AS VARCHAR(100) = '4'
DECLARE @COMP_NAME AS VARCHAR(100) = 'TAGASTE'
DECLARE @STREET_NUM AS VARCHAR(100) = '150'
DECLARE @STREET_NAME AS VARCHAR(100) = 'WILLSON'
DECLARE @STREET_TYPE AS INT = 1
DECLARE @SUB AS VARCHAR(100) = 'FAIRLANDS'
DECLARE @CITY AS VARCHAR(100) = 'JOHANNESBURG'
DECLARE @HOMEPHONE AS VARCHAR(100) = '0112355566'
DECLARE @EXISTS AS INT
DECLARE @ADD_ID AS INT

SET @EXISTS = (SELECT COUNT(ID) FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE=@HOMEPHONE 
AND COMPLEX_NUMBER = @COMP_NUM
AND COMPLEX_NAME = @COMP_NAME
AND STREET_NUMBER = @STREET_NUM
AND STREET_NAME = @STREET_NAME
AND STREET_TYPE = @STREET_TYPE
AND SUBURB = @SUB
AND CITY = @CITY)
PRINT ('COUNT ROWS: ' + CONVERT(CHAR(6),@EXISTS))

IF (CONVERT(INT,@EXISTS) > 0)               
BEGIN
    PRINT ('RECORD EXISTS')
    SET @ADD_ID = (SELECT ID FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE 
                    AND COMPLEX_NUMBER = @COMP_NUM
                    AND COMPLEX_NAME = @COMP_NAME
                    AND STREET_NUMBER = @STREET_NUM
                    AND STREET_NAME = @STREET_NAME
                    AND STREET_TYPE = @STREET_TYPE
                    AND SUBURB = @SUB
                    AND CITY = @CITY) 
    PRINT ('ADDRESS ID: ' + CONVERT(CHAR(6),@ADD_ID))
END
ELSE
BEGIN
    PRINT ('RECORD DOES NOT EXIST')
    INSERT INTO CARETEAMZ..ADDRESS_BOOK (HOME_PHONE, COMPLEX_NUMBER, COMPLEX_NAME, STREET_NUMBER, STREET_NAME,STREET_TYPE, SUBURB, CITY)
    VALUES (@HOMEPHONE, @COMP_NUM,@COMP_NAME, @STREET_NUM,@STREET_NAME,@STREET_TYPE,@SUB,@CITY)

    SET @ADD_ID = (SELECT ID FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE 
                    AND COMPLEX_NUMBER = @COMP_NUM
                    AND COMPLEX_NAME = @COMP_NAME
                    AND STREET_NUMBER = @STREET_NUM
                    AND STREET_NAME = @STREET_NAME
                    AND STREET_TYPE = @STREET_TYPE
                    AND SUBURB = @SUB
                    AND CITY = @CITY) 
    PRINT ('ADDRESS ID: ' + CONVERT(char(6),@ADD_ID))
END

Это мой полный курсор

DECLARE @COMP AS VARCHAR(500)
DECLARE @COMP_LENGTH AS INT
DECLARE @COMP_INDEX AS INT
DECLARE @COMP_NUM AS VARCHAR(50)
DECLARE @COMP_NAME AS VARCHAR(100)
DECLARE @STREET AS VARCHAR(500)
DECLARE @STREET_LENGTH AS INT
DECLARE @STREET_INDEX AS INT
DECLARE @STREET_NUM AS VARCHAR(50)
DECLARE @STREET_NAME AS VARCHAR(100)
DECLARE @STREET_VALUE AS VARCHAR(200)
DECLARE @STREET_TYPE AS INT
DECLARE @SUB AS VARCHAR(100)
DECLARE @CITY AS VARCHAR(100)
DECLARE @HOMEPHONE AS VARCHAR(100)
SET @CITY = 'JOHANNESBURG'

DECLARE ADD_CURSOR CURSOR FOR SELECT [HOME],[COMPLEX], [STREET] FROM #TEMPADD
OPEN ADD_CURSOR
FETCH NEXT FROM ADD_CURSOR INTO @HOMEPHONE,@COMP,@STREET;
    WHILE @@FETCH_STATUS = 0   
        BEGIN
            --COMPLEX DETAILS
            PRINT('-- COMPLEX DETAILS --')
            PRINT(@COMP) 
            SET @COMP_INDEX = CHARINDEX(',',@COMP)
            PRINT(@COMP_INDEX)
            IF (@COMP_INDEX > 0)
            BEGIN
                    PRINT('COMPLEX TRUE')
                    SET @COMP_NUM = LTRIM(RTRIM((SUBSTRING(@COMP,0,@COMP_INDEX))))
                    SET @COMP_NAME = LTRIM(RTRIM((SUBSTRING(@COMP,@COMP_INDEX+1,LEN(@COMP)))))                  
            END
            ELSE 
            BEGIN 
                    PRINT('COMPLEX FALSE')
                    SET @COMP_NUM = NULL
                    SET @COMP_NAME = NULL
            END
            PRINT('COMPLEX NUMBER: ' + CONVERT(VARCHAR(50),@COMP_NUM))
            PRINT('COMPLEX NAME: ' + @COMP_NAME)

            -- STREET ADDRESS
            PRINT('-- STREET NAME --')
            PRINT(@STREET) 
            SET @STREET_INDEX = CHARINDEX(',',@STREET)
            PRINT(@STREET_INDEX)
            IF (@STREET_INDEX > 0)
            BEGIN
                    PRINT('STREET TRUE')
                    SET @STREET_NUM = LTRIM(RTRIM((SUBSTRING(@STREET,0,@STREET_INDEX))))
                    SET @STREET = (SUBSTRING(@STREET,@STREET_INDEX+1,LEN(@STREET)))
                    PRINT(@STREET)
                    SET @STREET_INDEX = CHARINDEX(',',@STREET)
                    SET @STREET_NAME = LTRIM(RTRIM((SUBSTRING(@STREET,0,CHARINDEX(' ',@STREET)))))
                    SET @SUB = LTRIM(RTRIM((SUBSTRING(@STREET,@STREET_INDEX+1,LEN(@STREET)))))
                    SET @STREET_VALUE = SUBSTRING(@STREET,0,CHARINDEX(',',@STREET))
                    SET @STREET_TYPE = (SELECT ID FROM CARETEAMZ..STREET_TYPE WHERE STREET_TYPE = RTRIM(LTRIM((SUBSTRING(@STREET_VALUE,LEN(@STREET_VALUE)-CHARINDEX(' ',REVERSE(@STREET_VALUE))+2,LEN(@STREET_VALUE)-CHARINDEX(',',@STREET_VALUE))))))                  
            END
            ELSE 
            BEGIN 
                    PRINT('STREET FALSE')
                    SET @STREET_NUM = NULL
                    SET @STREET_NAME = NULL
                    SET @STREET_TYPE = NULL
                    SET @SUB = NULL
            END
            PRINT('STREET NUMBER: ' + @STREET_NUM)
            PRINT('STREET NAME: ' + @STREET_NAME)
            PRINT('STREET TYPE: ' + CONVERT(VARCHAR(10),@STREET_TYPE))
            PRINT('SUBURB: ' + @SUB)

            --CHECK IF THE ADDRESS / PHONE NUMBER ALREADY EXISTS IN THE DB
            DECLARE @ADD_ID AS INT
            DECLARE @EXISTS AS INT

            SET @EXISTS = (SELECT COUNT(ID) FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE 
            AND COMPLEX_NUMBER = @COMP_NUM
            AND COMPLEX_NAME = @COMP_NAME
            AND STREET_NUMBER = @STREET_NUM
            AND STREET_NAME = @STREET_NAME
            AND STREET_TYPE = @STREET_TYPE
            AND SUBURB = @SUB
            AND CITY = @CITY)
            PRINT ('COUNT ROWS: ' + CONVERT(CHAR(6),@EXISTS))
            IF (@EXISTS > 0)                
            BEGIN
                PRINT ('RECORD EXISTS')
                SET @ADD_ID = (SELECT ID FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE 
                                AND COMPLEX_NUMBER = @COMP_NUM
                                AND COMPLEX_NAME = @COMP_NAME
                                AND STREET_NUMBER = @STREET_NUM
                                AND STREET_NAME = @STREET_NAME
                                AND STREET_TYPE = @STREET_TYPE
                                AND SUBURB = @SUB
                                AND CITY = @CITY)

                PRINT ('ADDRESS ID: ' + CONVERT(CHAR(6),@ADD_ID))
            END
            ELSE
            BEGIN
                PRINT ('RECORD DOES NOT EXIST')
                INSERT INTO CARETEAMZ..ADDRESS_BOOK (HOME_PHONE, COMPLEX_NUMBER, COMPLEX_NAME, STREET_NUMBER, STREET_NAME,STREET_TYPE, SUBURB, CITY)
                VALUES (@HOMEPHONE, @COMP_NUM,@COMP_NAME, @STREET_NUM,@STREET_NAME,@STREET_TYPE,@SUB,@CITY)

                SET @ADD_ID = (SELECT ID FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE 
                                AND COMPLEX_NUMBER = @COMP_NUM
                                AND COMPLEX_NAME = @COMP_NAME
                                AND STREET_NUMBER = @STREET_NUM
                                AND STREET_NAME = @STREET_NAME
                                AND STREET_TYPE = @STREET_TYPE
                                AND SUBURB = @SUB
                                AND CITY = @CITY) 

                PRINT ('ADDRESS ID: ' + CONVERT(char(6),@ADD_ID))

            END

            --FETCH NEXT
            FETCH NEXT FROM ADD_CURSOR INTO @HOMEPHONE,@COMP, @STREET;
        END
CLOSE ADD_CURSOR;
DEALLOCATE ADD_CURSOR;

Хорошо, я посмотрел оба ответа @HLGEM и @kuru kuru pa. @HLGEM Это лишь небольшая часть более крупного курсора, и, к сожалению, MERGER SQL не будет работать для моих текущих потребностей. Я не беспокоюсь о производительности, так как это просто импорт данных в мою базу данных.

@ kuru kuru pa - хороший ответ, но, к сожалению, у меня все еще возникает та же проблема. 1-й раз, когда я запускаю курсор, он работает на 100%. Вставляет все значения, второй раз он должен возвращать только идентификаторы, но id ничего не возвращает и вставляет дубликаты.

Ниже приведены два оператора создания таблицы с некоторыми фиктивными данными.

TEMP TABLE

CREATE TABLE #TEMPADD
(
    HOME VARCHAR(100) NULL,
    COMPLEX VARCHAR(100) NULL,
    STREET VARCHAR(100) NULL,
)

INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 6787',  '32,Tagaste',   '150,Willson Street, Land')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 1909',  NULL,   '29,Bunkara Street, Rio')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 689 2630',  NULL,   '275,Kings Lynne Road, Glen')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    NULL,   '275,Kings Lynne Road, Glen')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 799 5917',  '5,The Vineyard',   '45,Hilary Road, Ridge')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '5,The Vineyard',   '45,Hilary Road, Ridge')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 5857',  NULL,   '11A,Alexandra Street, Florida')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 5857',  NULL,   '11A,Alexandra Street, Florida')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 3225',  NULL,   '752, Without Avenue, Weltevreden')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 8909',  NULL,   '18,Smit Street,Land')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES ('011 679 8909',  '512,Athenian View',    '158,Smit Street, Fairland')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    '741,Eagle Trace Landing',  'Eagle Canyon Golf Estate, Honey')
INSERT INTO #TEMPADD (HOME,COMPLEX,STREET) VALUES (NULL,    NULL,   '106A,3rd Avenue, Land')

АДРЕСНЫЙ СТОЛ

CREATE TABLE [dbo].[ADDRESS_BOOK](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [PoBox] [varchar](50) NULL,
    [Complex_Number] [varchar](50) NULL,
    [Complex_Name] [varchar](100) NULL,
    [Street_Number] [varchar](50) NULL,
    [Street_Name] [varchar](100) NULL,
    [Street_Type] [int] NULL,
    [Suburb] [varchar](100) NULL,
    [City] [varchar](50) NULL,
    [Code] [varchar](50) NULL,
    [Home_Phone] [varchar](50) NULL
) ON [PRIMARY]

Ответы [ 2 ]

1 голос
/ 07 сентября 2011

С какой стати вы бы использовали курсор для этого?Предлагаем вам прочитать эту статью, чтобы увидеть, насколько проще (и быстрее) это сделать, используя методы на основе множеств:

http://wiki.lessthandot.com/index.php/Cursors_and_How_to_Avoid_Them

0 голосов
/ 07 сентября 2011

Это большой код для чтения ...

Первое наблюдение (не ответ на ваш вопрос, но FWIW) заключается в том, что вы, возможно, используете не тот инструмент для этой работы. Не уверен, что курсор необходим здесь. Во всяком случае ...

На данный момент просто выборочная проверка ... (если вы не хотите добавить скрипт создания таблицы, предложенный @martin ... (я дам вам более подробный ответ, если вы это сделаете)

Ваше использование @Exists излишне. По сути, вы используете @Exists, чтобы сообщить, существует ли @Add_ID. Это косвенный / избыточный подход.

If @Exists exists, then @Add_ID exists.

Вы можете использовать гораздо более скучную тавтологию (прямой подход):

If @Add_ID exists, then @Add_ID exists.

Итак, ваш код может быть таким:

SET @Exists = ...
If @Exits > 0...

SET @ADD_ID = (SELECT ID FROM CARETEAMZ..ADDRESS_BOOK WHERE HOME_PHONE = @HOMEPHONE AND ...)
IF @ADD_ID IS NOT NULL
BEGIN
   PRINT(...)
END
ELSE...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...