SQL при вставке во временные таблицы ошибки уже существуют, но я предварительно очищаю таблицы - PullRequest
0 голосов
/ 03 апреля 2019

Я не уверен, почему это происходит, но когда я запускаю какой-то код, который принимает длинную строку с несколькими значениями, я получаю случайную ошибку. Предполагается, что ошибка заключается в том, что я пытаюсь выполнить вставку во временную таблицу, которая уже существует, хотя я не уверен, насколько это возможно, поскольку внутри вершины первого базового цикла я отбрасываю таблицы, если они существуют. Таким образом, их может использовать предыдущий прогон, при необходимости они сбрасываются и снова проходят.

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

Вот полная хранимая процедура. Кроме того, я стек разработчика, так что если у вас есть хорошие указатели для этого запроса, пожалуйста, не стесняйтесь делать заметки. Заранее спасибо.

Строка ДАННЫХ для тестирования, которая может возникнуть в этой процедуре:

MITUTOYO ~ 103-217 ~ DESC ~ ^ Браун и Шарп ~ 73 ~ DESC ~ ^ MITUTOYO ~ 103-188 ~ DESC ~ ^ MITUTOYO ~ 103-224A ~ DESC ~ ^ MITUTOYO ~ 103-225A ~ DESC ~ ^ MITUTOYO ~ 103-225A ~ DESC ~ ^ MITUTOYO ~ 103-189A ~ DESC ~ ^

Для каждого из основных значений multi в символе ^ мы ищем производителя и модель и видим, существует ли он. Если это так, верните его, если нет, верните его с новым списком предложений с несколькими значениями в столбце SuggesList. Вот пример одного отправленного элемента, затем совпадений не найдено, так же как и нечеткий поиск.

Производитель ПроизводительPartNumber ПроизводительОписание Цена ItemType MfrНайдено моделиНайдено баллов ПредложениеГруппа

Анализатор сети, 0,00, NA, 0, 1, 0, СТАНДАРТ, ИСПОЛЬЗОВАНИЕ ДЛЯ HYPRO STANDARD BORE GAGES, 31.00,6, ^ Харви Уэллс, FORCE GAGE ​​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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...