0

我有一個帶有地址信息的#temptable,它正在使用遊標讀取。光標效果很好。遊標中的if語句爲#table中的第一條記錄工作100%,但對於第二條記錄,它總是返回false。Microsoft SQL Server 2008光標

if語句的想法是檢查db中地址表中存在的值,然後如果它確實獲取了id。如果沒有,則插入該行並獲取該ID。獨立的if語句工作100%。我將它添加到光標的那一刻就打破了。它就好像變量以某種方式被覆蓋一樣。

因此,如果我的#table中包含相同的行,那麼該行仍會插入兩次到address_table中而不是一次。第一次,如果它不存在的地址被插入,地址在表中的ID應該retured

第二次我已經採取了打印語句在那裏我做了轉換(),它不似乎有所作爲。

這是獨立的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 [email protected] 
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庫魯PA的答案。 @HLGEM這只是較大遊標的一小部分,不幸的是,MERGER SQL不適合我目前的需求。我不擔心性能,因爲這只是將數據導入我的數據庫。

@kuru kuru pa的回答是很好的答案,但不幸的是我似乎仍然得到同樣的問題。我第一次運行光標它運行100%。插入所有的值,第二次它應該只返回ID,但ID不會返回任何內容並插入重複項。

下面是包含一些虛擬數據的2表創建語句。

TEMP表

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] 
+4

說實話,我會更傾向於看這個了,你包含了一些'創建table'腳本,這樣我可以運行它。我不明白爲什麼當它是一個'int'時將'@ Exists'轉換爲'int'? –

+0

我已經發布的代碼爲您創建表... ...謝謝你的幫助迄今爲止... – H2wk

回答

0

這是一個很大的代碼來通讀...

首先觀察(不是對你的問題的回答,而是FWIW)是,你可能會使用錯誤的工具來完成這項工作。不確定在這裏需要光標。反正...

只需點檢查現在...(除非你想添加的創建表腳本@馬丁建議......(我給你一個更完整的答案,如果你這樣做)

您對@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... 
1

爲什麼地球上,你會使用遊標做到這一點?建議你閱讀這篇文章,看看它是多麼容易(以及更快的)使用基於集合的方法做:

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

+0

的方式大遺址..不幸合併SQL是不會解決我的問題......這光標剛大局觀的一小部分......不要擔心回合的性能無論是作爲它只會被運行一次來​​填充空白分貝......我已經發布了光標上運行的表的代碼... – H2wk