插入临时表时出现SQL错误,但已经存在污点,但我先清理了表

时间:2019-04-03 19:20:15

标签: sql sql-server

我不确定为什么会这样,但是当我运行一些需要较长的多值子值字符串的代码时,会出现随机错误。错误可能是因为我试图在已经存在的临时表中进行插入,尽管我不确定这样做是如何进行的,因为在第一个基本循环的顶部,如果存在的话就将其删除。这样,先前的运行就可以使用它们,如果需要,它们会掉落并再次运行。

现在我几乎可以肯定另一个错误正在失败,然后导致产生误导性的返回消息,但不确定。

这是完整的存储过程。另外,我是一个堆栈开发人员,因此,如果您对此查询有任何好的指针,请随时注意。预先感谢。

可能用于此过程的测试数据字符串:

  

MITUTOYO〜103-217〜DESC〜^ BROWN&SHARPE〜73〜DESC〜^ MITUTOYO〜103-188〜DESC〜^ MITUTOYO〜103-224A〜DESC〜^ MITUTOYO〜103-225A〜DESC〜^ MITUTOYO〜 103-225A〜DESC〜^ MITUTOYO〜103-189A〜DESC〜^

对于^字符内的每个主要多值,我们将查找制造商和模型,并查看它们是否存在。如果是这样,则返回它;如果不是,则返回它,并在RecommendationsList列中带有新的多值建议列表。这是一个发送的示例,然后找不到匹配项,因此模糊查找也是如此。

  

制造商ManufacturerPartNumber制造商描述价格项目类型MfrFound模型找到分数建议组

     

Analyzer Network,0.00,NA,0、1、0,STANDARD,用于HYPRO STANDARD BORE   GAGES,31.00,6,^ Harvey Wells ,, FORCE GAUGE 0 35 GMS,93.50,0,^

完整的存储过程:

ALTER PROCEDURE DATA_FuzzyAssetMatchLARGE
/*
    PROP: @LISTIN - The entire multi file string sent in from the data file of records.
    I=Since the records sent in are a multi value record of sub values meaning (v1.Mfr, v1.Model, v1.Description ^ v2.Mfr, v2.Model, v2.Description ^ ....)
    we could in theory have thousands of records to n(3) of string length unknown (n). This being said, we set the value to varchar(max).

    varchar(max) unlike varchar wich holds (8000 characters max about 65k bytes), varchar(max) can hold 2 gigs worth of data. That equates to about
    1 billion characters since in .NET and others one CHAR is a 2 byte system. This holds mroe then enough.
*/
@LISTIN VARCHAR(MAX)
 AS 
BEGIN
   SET NOCOUNT ON;
   SET ARITHABORT OFF 
   SET ANSI_WARNINGS OFF
   SET FMTONLY OFF

declare @errorMessage varchar(150) -- ideally would be nice to append to each row so we knew what failed but not break and continue. Not like that at moment

-- ITEMS USED FOR TOP LEVEL RECURSIVE SPLIT LOOP --    
declare @pos INT;
declare @len INT;
declare @value varchar(max); -- the value of the first splits (objects) delimed by the ^ character
-- Counter varaibles used to loop and build the one column Suggestion of all matching items
declare @MaxCount integer;
declare @Count integer;
declare @suggestionsStringBuilder varchar(350); --holds the built list of any suggestions.
declare @objectManufacturer varchar(100);
declare @objectModel varchar(150);
declare @objectDescription varchar(150);  --the context for this instance to run the params selects for Mfr, Model, Desc
declare @counterIndex int = 0;
declare @objectString varchar(250);
--USED FOR SECOND LEVEL RECURSIVE SPLIT LOOP
declare @objectPosVal INT;
declare @objectLenVal INT;
declare @objectSubstring varchar(250); -- the value used for the secondary split (each object properties such as the actual Mfr, Model, Description, so on....)

--cursor declerations
DECLARE @suggestionsListCursor CURSOR;
DECLARE @CURSOR_Mfr varchar(150);
DECLARE @CURSOR_Model varchar(150);
DECLARE @CURSOR_Desc varchar(150);
DECLARE @CURSOR_Type varchar(20);
DECLARE @CURSOR_Price MONEY;
DECLARE @CURSOR_Score int;

--TEMP TABLE TO STORE FUZZY PREDFINED TABLES IN
IF OBJECT_ID('BASE') IS NOT NULL DROP TABLE BASE

--CREATE THE TEMPTABLE TO WORK WITH
CREATE TABLE BASE
(
    Manufacturer varchar(150) null, 
    ManufacturerPartNumber Varchar(100) null, 
    ManufacturerDescription varchar(150) null,
    Score int ,
    Price money,
    ItemType varchar(20),
    ModelFound bit not null,
    MfrFound bit not null, 
    SuggestionGroup varchar(MAX) null 
)


--THIS IS THE LOOP TO PREPARE THE DELIM STRING AND DO A FUZZY MATH OR STRAIGHT MATCH ON EACH OBJECT ROW
set @pos = 0;
set @len = 0;

while charindex('^', @LISTIN, @pos+1)>0
    begin
    if object_id('tempdb..#TEMPPMFR') is not null drop table #TEMPPMFR
    if object_id('tmpdb..#TEMPPMFRMODEL') is not null drop table #TEMPPMFRMODEL

    -- stop if there was an error --
    if(@errorMessage is not null and @errorMessage  != '')
        break;

    set @suggestionsStringBuilder = '';
    set @len = charindex('^', @LISTIN, @pos+1) - @pos;
    set @VALUE = substring(@LISTIN,@POS,@LEN-1); 
    set @objectLenVal = 0;
    set @objectPosVal = 0;
    set @counterIndex = 0;


    set @suggestionsStringBuilder = ''
    set @objectManufacturer = ''
    set @objectModel = ''
    set @objectDescription = ''

    --THE LIST COMING IN IS A MULTI-DEMENSIONAL ARRAY OR MULTI-VALUE. IT IS A GROUP OF ENTITYIES, THEN EACH
    --ENTITYT IS A GROUP OF PROPERTIES. OUR OUTTER LOOP WE SPLIT ON ENTITITIES.
    -- EXAMPLE: @F, @M, @D = Manufacturer, odel, Description
    while charindex('~', @value, @objectPosVal+1)>0
        begin
            set @objectLenVal = charindex('~', @value, @objectPosVal+1) - @objectPosVal
            set @objectSubstring = substring(@value, @objectPosVal, @objectLenVal)

            if(@counterIndex=0) 
                set @objectManufacturer = LTRIM(RTRIM(@objectSubstring)) 
            else if(@counterIndex=1) 
                set @objectModel = LTRIM(RTRIM(@objectSubstring))
            else 
                begin
                set @objectDescription = LTRIM(RTRIM(@objectSubstring)) 
                break 
                end

            set @objectPosVal = charindex('~', @value, @objectPosVal+@objectLenVal) +1
        end 

        -- ****
        -- **** WE HAVE THE MANUFACTURER AND THE MODEL SO JUST RETURN THE DATA 
        -- ****
        if((select top 1 1 FROM Products_OurProducts_Products where Manufacturer = @objectManufacturer and ManufacturerPartNumber = @objectModel) > 0)
            begin try  
                insert into BASE (
                     Manufacturer
                    ,ManufacturerPartNumber
                    ,ManufacturerDescription
                    ,Price,ItemType
                    ,MfrFound
                    ,ModelFound
                    ,Score
                    ,SuggestionGroup
                ) 
                select 
                    POP.Manufacturer
                    ,POP.ManufacturerPartNumber as Model
                    ,POP.Description
                    ,CONVERT(money,POP.Price) as Price
                    ,POP.ItemType
                    ,CAST('1' as bit) as MfrFound
                    ,CAST('1' as bit) as ModelFound
                    ,CAST('-1' as int) as Score
                    ,'' as SuggestionGroup  
                from 
                    Products_OurProducts_Products as POP
                where 
                    POP.Manufacturer = @objectManufacturer 
                        and 
                    POP.ManufacturerPartNumber = @objectManufacturer        
            end try  
            begin catch
                SET @errorMessage = (
                    select  
                        'Number: ' + CAST(ERROR_NUMBER() as varchar(15)) +  ' Message:' + ERROR_MESSAGE() AS ErrorMessage
                    ); 
            end catch
        else
        -- ****
        -- **** WE EITHER FOUND MANUFACTURER SO FUZZY ON MODEL OR VICE VERSA
        -- ****
            begin try 
                if((select top 1 1 from Products_OurProducts_Products where Manufacturer = @objectManufacturer) > 0)
                    begin
                    --we have to build these temp tables os dynamic columns exist such as MfrFound, ModelFound              
                    select 
                        PMFR.Manufacturer
                        ,PMFR.ManufacturerPartNumber
                        ,PMFR.Description AS ManufacturerDescription
                        ,convert(money,PMFR.Price) as Price
                        ,PMFR.ItemType
                        ,cast('1' as bit) as MfrFound
                        ,cast('0' as bit) as ModelFound
                        ,'' as SuggestionGroup
                    into 
                        #TEMPPMFR
                    from 
                        Products_OurProducts_Products as PMFR
                    where 
                        PMFR.Manufacturer = @objectManufacturer

                    set @SuggestionsListCursor = cursor for
                        select top 5 
                            P.Manufacturer
                           ,P.ManufacturerPartNumber as Model
                           ,P.ManufacturerDescription AS 'Description'
                           ,P.Price
                           ,fms.score as Score
                        from #TEMPPMFR as P
                            cross apply (
                                select 
                                    dbo.FuzzyControlMatch(@objectModel, P.ManufacturerPartNumber) AS score
                                ) as fms
                        where 
                            P.Manufacturer = @objectManufacturer
                        order by 
                            fms.score 
                        desc

                    open @SuggestionsListCursor 

                    fetch next from 
                        @SuggestionsListCursor 
                    into 
                        @CURSOR_Mfr
                       ,@CURSOR_Model
                       ,@CURSOR_Desc
                       ,@CURSOR_Price
                       ,@CURSOR_Score

                    while @@FETCH_STATUS = 0
                    begin
                        if @suggestionsStringBuilder!='' 
                            set @suggestionsStringBuilder=@suggestionsStringBuilder + @CURSOR_Mfr + ',' + @CURSOR_Model + ',' + @CURSOR_Desc + ',' + convert(varchar(20),@CURSOR_Price) + ',' + convert(varchar(4),@CURSOR_Score) + ', ^ '  
                        else 
                            set @suggestionsStringBuilder = @CURSOR_Mfr + ',' + @CURSOR_Model + ',' + @CURSOR_Desc + ',' + convert(varchar(20),@CURSOR_Price) + ',' + convert(varchar(4),@CURSOR_Score) + ', ^ '

                        fetch next from 
                            @SuggestionsListCursor 
                        into 
                            @CURSOR_Mfr
                           ,@CURSOR_Model
                           ,@CURSOR_Desc
                           ,@CURSOR_Price
                           ,@CURSOR_Score
                    end

                    --Now we insert the original Mfr, Model, Desc, and the suggestions list we build
                    insert into BASE values(
                        @objectManufacturer
                       ,@objectModel
                       ,@objectDescription
                       ,'0'
                       ,'0'
                       ,'NA'
                       ,'1'
                       ,'0'
                       ,@suggestionsStringBuilder
                     )

                    close @SuggestionsListCursor
                    deallocate @SuggestionsListCursor
                end
                else
                    --IF HAVE A FUZZY AT MFR, THEN WE NEED TO GRAB BEST CHOICE AND GO DOWN. 
                    --WE COULD HAVE POSIBLY CANDIDATES FOR THIS SO WHEN TO STOP RECURSIVENESS AND SAY ADDING NEW ENTRY? 
                    begin
                    --AT MOMENT JUST RETURN TOP FOUND MFR THEN SELECT FROM THAT TO SEE RESULT TESTS
                    --FIRST LETS SEE IF SENT MODEL EXIST AND IF SO, PULL THAT THEN RANK AGAINST MFR FOR IT
                    if((select top 1 1 from Products_OurProducts_Products where ManufacturerPartNumber = @objectModel) > 0)
                        begin
                            select 
                                Manufacturer
                               ,ManufacturerPartNumber
                               ,Description AS ManufacturerDescription
                               ,CONVERT(money,Price) AS Price
                               ,ItemType
                               ,CAST('0' as bit) as MfrFound
                               ,CAST('1' as bit) as ModelFound
                               ,'' as SuggestionGroup 
                             into 
                                #TEMPPMFRMODEL
                             from 
                                Products_OurProducts_Products
                             where 
                                ManufacturerPartNumber = @objectModel

                             set @SuggestionsListCursor = cursor for 
                                    select top 5 
                                        P.Manufacturer
                                       ,P.ManufacturerPartNumber as Model
                                       ,P.ManufacturerDescription as 'Description'
                                       ,P.Price
                                       ,fms.score as Score
                                    from #TEMPPMFRMODEL AS P
                                        CROSS APPLY (
                                            select 
                                                dbo.FuzzyControlMatch(@objectManufacturer, P.Manufacturer) AS score
                                            ) AS fms
                                    where 
                                        P.ManufacturerPartNumber = @objectModel
                                    order by 
                                        fms.score 
                                    desc

                                --OPEN CURSOR NOW--
                                open @SuggestionsListCursor

                                -- NOW LOOP THE RESULTS AND BUILD DEMLIMETER STRING OF SUGESTIONS FOR MFR-- 
                                fetch next from @SuggestionsListCursor into @CURSOR_Mfr, @CURSOR_Model, @CURSOR_Desc, @CURSOR_Price, @CURSOR_Score 

                                while @@FETCH_STATUS = 0
                                    begin
                                        if @suggestionsStringBuilder != '' 
                                            set @suggestionsStringBuilder = @suggestionsStringBuilder + @CURSOR_Mfr + ',' + @CURSOR_Model + ',' + @CURSOR_Desc + ',' + convert(varchar(20),@CURSOR_Price) + ',' + convert(varchar(4),@CURSOR_Score) + ', ^ '  
                                        else 
                                            set @suggestionsStringBuilder = @CURSOR_Mfr + ',' + @CURSOR_Model + ',' + @CURSOR_Desc + ',' + convert(varchar(20),@CURSOR_Price) + ',' + convert(varchar(4),@CURSOR_Score) + ', ^ '

                                        fetch next from @SuggestionsListCursor 
                                        into @CURSOR_Mfr, @CURSOR_Model, @CURSOR_Desc, @CURSOR_Price, @CURSOR_Score
                                    end

                                insert into BASE values(
                                    @objectManufacturer
                                   ,@objectModel
                                   ,@objectDescription
                                   ,'0'
                                   ,'0'
                                   ,'NA'
                                   ,'1'
                                   ,'0'
                                   ,@suggestionsStringBuilder
                                  )

                                close @SuggestionsListCursor ;
                                deallocate @SuggestionsListCursor ;
                            end
                    else
                        insert into BASE values(
                            @objectManufacturer
                            ,@objectModel
                            ,@objectDescription
                            ,'0'
                            ,'0'
                            ,'NA'
                            ,'0'
                            , '0'
                            , ''
                        )       
                    end
                    --THEN SEE IF EXIST USING FUZZY FOUND MFR, TO SEEK MODEL NUMBER ETC.
            END TRY  
            BEGIN CATCH
                SET @errorMessage = (
                    select  
                        'Number: ' + CAST(ERROR_NUMBER() as varchar(15)) +  ' Message:' + ERROR_MESSAGE() AS ErrorMessage
                    );  
            END CATCH

        SET @pos = CHARINDEX('^', @LISTIN, @pos+@len) +1
    END

 if(@errorMessage is not null and @errorMessage != '')
        select @errorMessage as 'ErrorInfo'
else
    select 
        Manufacturer
        ,ManufacturerPartNumber
        ,ManufacturerDescription
        ,Price
        ,ItemType
        ,MfrFound
        ,ModelFound
        ,Score
        ,SuggestionGroup 
    from 
        BASE

--NOW REMOVE THE TEMP TABLE
If(OBJECT_ID('BASE') Is Not Null)
    BEGIN
        DROP TABLE BASE
    END
IF(OBJECT_ID('tempdb..#TEMPPMFR') IS NOT NULL)
    BEGIN
        DROP TABLE #TEMPPMFR
    END
IF(OBJECT_ID('tmpdb..#TEMPPMFRMODEL') IS NOT NULL)
    BEGIN 
        DROP TABLE #TEMPPMFRMODEL 
    END
 END
 GO

0 个答案:

没有答案