SQLServer:存储过程不会添加任何数据而不会出现任何错误

时间:2019-06-26 10:31:08

标签: sql sql-server

我有两个表主和详细信息。我将xml传递给存储过程作为参数值,但是当执行存储过程代码时,则不会插入任何数据,也不会引发任何错误。我无法理解问题所在。

任何人都可以帮助我在导致问题的商店过程代码中找到错误的区域。

     /bin/bash: warning: here-document at line 0 delimited by end-of-file (wanted 'Kaggle username')
/bin/bash: warning: here-document at line 0 delimited by end-of-file (wanted `Kaggle password')
/usr/local/lib/python3.6/dist-packages/mechanicalsoup/browser.py:37: UserWarning: No parser was explicitly specified, so I'm using the best available HTML parser for this system ("lxml"). This usually isn't a problem, but if you run this code on another system, or in a different virtual environment, it may use a different parser and behave differently.
The code that caused this warning is on line 37 of the file /usr/local/lib/python3.6/dist-packages/mechanicalsoup/browser.py. To get rid of this warning, pass the additional argument 'features="lxml"' to the BeautifulSoup constructor.



response.content, **soup_config)
'Response' object has no attribute 'soup'

编辑

我这样解决了

Table code
-------------

CREATE TABLE TblTickerTemplate (
    ID int identity,
    Ticker varchar(20),
    LineItem varchar(100),
    Insertdate datetime DEFAULT GETDATE()

    CONSTRAINT PK_ID PRIMARY KEY CLUSTERED (ID)
);

ALTER Table TblTickerTemplate
Add CONSTRAINT UC_Ticker_LineItem UNIQUE (Ticker, LineItem)

CREATE TABLE TblTickerTemplateDetail (
    MasterTemplateID int,
    ID int identity,
    LineItem varchar(100),
    XFundCode varchar(100),
    Action Char(1),
    UserID varchar(20),
    Insertdate datetime DEFAULT GETDATE()
    FOREIGN KEY(MasterTemplateID) REFERENCES TblTickerTemplate(ID)
);

Procedure code
-------------
ALTER Procedure USP_InsertUniqueLineItems
(
    @INPUTXML xml,
    @STATUS VARCHAR(MAX) OUTPUT  
)

AS 

BEGIN
    SET NOCOUNT ON

    BEGIN TRANSACTION   
    BEGIN TRY  
        Declare @TblTickerTemplateDetailID  AS INT 

        Declare @XMLFormat                  AS INT

        Declare @Ticker                     AS VARCHAR(MAX)
        Declare @ID                         AS INT
        Declare @Lineitem                   AS VARCHAR(MAX)
        Declare @XFundCode                  AS VARCHAR(MAX)
        Declare @UserID                     AS VARCHAR(MAX)

        --load xml data into cursor
        Exec sp_xml_preparedocument @XMLFormat OUTPUT, @INPUTXML

        DECLARE CURRECORD
        CURSOR LOCAL FOR
        SELECT Ticker,ID,Lineitem,XFundCode,@UserID
        FROM OPENXML (@XMLFORMAT, '/Lineitems', 1)
        WITH (
            Ticker                  VARCHAR(MAX),
            ID                      INT,
            Lineitem                VARCHAR(MAX),
            XFundCode               VARCHAR(MAX),
            UserID                  VARCHAR(MAX)
         )


        SET @TblTickerTemplateDetailID = 0

        -- open cursor
        OPEN CURRECORD
        FETCH NEXT FROM CURRECORD INTO @Ticker,@ID,@Lineitem,@XFundCode,@UserID

        -- iterate in cursor to fetch value
        WHILE (@@FETCH_STATUS=0)
        BEGIN

            -- if ID == 0 then new data it will be inserted in TblTickerTemplate & TblTickerTemplateDetail table
            IF @ID = 0
            BEGIN
                IF NOT EXISTS(SELECT LineItem  FROM TblTickerTemplate WHERE LineItem = @Lineitem AND Ticker = @Ticker)
                BEGIN
                    INSERT INTO TblTickerTemplate(Ticker,LineItem)
                        VALUES (@Ticker,@Lineitem)

                    SET @TblTickerTemplateDetailID = SCOPE_IDENTITY()

                    INSERT INTO TblTickerTemplateDetail (MasterTemplateID,LineItem,XFundCode,UserID,[Action])
                        VALUES (@TblTickerTemplateDetailID,@Lineitem,@XFundCode,@UserID,'I')                    
                END
            END
            ELSE
            BEGIN
                    -- if ID > 0 means existing data & the data will be inserted in TblTickerTemplateDetail table only

                    INSERT INTO TblTickerTemplateDetail (MasterTemplateID,LineItem,XFundCode,UserID,[Action])
                        VALUES (@ID,@Lineitem,@XFundCode,@UserID,'U')
            END

        FETCH NEXT FROM CURRECORD INTO @Ticker,@ID,@Lineitem,@XFundCode,@UserID
        END

        IF @ID = 0
        BEGIN                       
            SET @STATUS='New Line items successfully inserted' 
        END
        ELSE IF @ID > 0
        BEGIN     
            SET @STATUS='Existing Line items successfully updated' 
        END

        CLOSE CURRECORD
        DEALLOCATE CURRECORD    
        COMMIT TRANSACTION



    END TRY  

    BEGIN CATCH  

        DECLARE @ERROR INT, @MESSAGE VARCHAR(4000)
        SELECT @ERROR = ERROR_NUMBER(),@MESSAGE = ERROR_MESSAGE()   

        --SET @STATUS='Line items insert fail' 
        ROLLBACK TRANSACTION 

        RAISERROR ('USP_InsertUniqueLineItems:', 16, 1, @ERROR, @MESSAGE) 
        --SET @STATUS='Fail-- '+@MESSAGE
        --RETURN

    END CATCH;

    SET NOCOUNT OFF
END

Calling procedure this way
--------------------------

Declare @inputxml xml  
Declare @Status VARCHAR(MAX)

 set @inputxml='<Lineitems>
  <Lineitem>
    <Ticker>TER</Ticker>
    <ID>0</ID>
    <LineItem>Net Revenue</LineItem>
    <XFundCode>TRIN</XFundCode>
    <UserID>TDP</UserID>
  </Lineitem>
  <Lineitem>
    <Ticker>TER</Ticker>
    <ID>0</ID>
    <LineItem>Cost of Revenue</LineItem>
    <XFundCode>XXP</XFundCode>
    <UserID>TDP</UserID>    
  </Lineitem>
</Lineitems>'

 EXEC [dbo].USP_InsertUniqueLineItems @inputxml, @Status output

 Select @Status

但是,如果我取消注释此行/* SAMPLE XML to insert <Lineitems> <Lineitem> <Ticker>TER</Ticker> <ID>0</ID> <LineItem>Net Revenue</LineItem> <XFundCode>TRIN</XFundCode> <UserID>TDP</UserID> </Lineitem> <Lineitem> <Ticker>TER</Ticker> <ID>0</ID> <LineItem>Cost of Revenue</LineItem> <XFundCode>XXP</XFundCode> <UserID>TDP</UserID> </Lineitem> </Lineitems> */ ALTER Procedure USP_InsertUniqueLineItems ( @INPUTXML xml, @STATUS VARCHAR(MAX) OUTPUT ) AS BEGIN SET NOCOUNT ON BEGIN TRANSACTION BEGIN TRY Declare @TblTickerTemplateDetailID AS INT Declare @XMLFormat AS INT Declare @Ticker AS VARCHAR(MAX) Declare @ID AS INT Declare @Lineitem AS VARCHAR(MAX) Declare @XFundCode AS VARCHAR(MAX) Declare @UserID AS VARCHAR(MAX) --load xml data into cursor Exec sp_xml_preparedocument @XMLFormat OUTPUT, @INPUTXML DECLARE CURRECORD CURSOR LOCAL FOR SELECT ID,Ticker,LineItem,XFundCode,UserID FROM OPENXML (@XMLFORMAT, '/Lineitems/Lineitem', 2) WITH ( ID INT, Ticker VARCHAR(MAX), LineItem VARCHAR(MAX), XFundCode VARCHAR(MAX), UserID VARCHAR(MAX) ) SET @TblTickerTemplateDetailID = 0 -- open cursor OPEN CURRECORD FETCH NEXT FROM CURRECORD INTO @ID,@Ticker,@Lineitem,@XFundCode,@UserID -- iterate in cursor to fetch value WHILE (@@FETCH_STATUS=0) BEGIN -- if ID == 0 then new data it will be inserted in TblTickerTemplate & TblTickerTemplateDetail table IF @ID = 0 BEGIN IF NOT EXISTS(SELECT * FROM TblTickerTemplate WHERE LineItem = @Lineitem AND Ticker = @Ticker) BEGIN Print @Ticker+' '+@Lineitem INSERT INTO TblTickerTemplate(Ticker,LineItem) VALUES (@Ticker,@Lineitem) SET @TblTickerTemplateDetailID = SCOPE_IDENTITY() SET @STATUS='New Line items successfully inserted' INSERT INTO TblTickerTemplateDetail (MasterTemplateID,LineItem,XFundCode,UserID,[Action]) VALUES (@TblTickerTemplateDetailID,@Lineitem,@XFundCode,@UserID,'I') END END ELSE BEGIN -- if ID > 0 means existing data & the data will be inserted in TblTickerTemplateDetail table only INSERT INTO TblTickerTemplateDetail (MasterTemplateID,LineItem,XFundCode,UserID,[Action]) VALUES (@ID,@Lineitem,@XFundCode,@UserID,'U') END FETCH NEXT FROM CURRECORD INTO @ID,@Ticker,@Lineitem,@XFundCode,@UserID END -- storing message to OUTPUT type variable IF @ID = 0 BEGIN SET @STATUS='New Line items successfully inserted' END ELSE IF @ID > 0 BEGIN SET @STATUS='Existing Line items successfully updated' END CLOSE CURRECORD DEALLOCATE CURRECORD COMMIT TRANSACTION END TRY BEGIN CATCH -- Error handling part DECLARE @ERROR INT, @MESSAGE VARCHAR(4000) SELECT @ERROR = ERROR_NUMBER(),@MESSAGE = ERROR_MESSAGE() SET @STATUS='Fail-- '+@MESSAGE ROLLBACK TRANSACTION --RAISERROR ('USP_InsertUniqueLineItems:', 16, 1, @ERROR, @MESSAGE) RETURN END CATCH; SET NOCOUNT OFF END ,那么错误就来了。如何解决...分享一些想法。谢谢

3 个答案:

答案 0 :(得分:1)

嗨,请在插入时尝试使用此代码。

Declare @inputxml xml  


 set @inputxml='<Lineitems>
  <Lineitem>
    <Ticker>TER</Ticker>
    <ID>1</ID>
    <LineItem>Net Revenue</LineItem>
    <XFundCode>TRIN</XFundCode>
    <UserID>TDP</UserID>
  </Lineitem>
  <Lineitem>
    <Ticker>TER</Ticker>
    <ID>2</ID>
    <LineItem>Cost of Revenue</LineItem>
    <XFundCode>XXP</XFundCode>
    <UserID>TDP</UserID>    
  </Lineitem>
</Lineitems>'


        SELECT

      T.C.value('(ID)[1]', 'int')

      ,T.C.value('(Ticker)[1]', 'varchar(max)')

      ,T.C.value('(LineItem)[1]', 'varchar(max)')

      ,T.C.value('(XFundCode)[1]', 'varchar(max)')
      ,T.C.value('(UserID)[1]', 'varchar(max)')


   FROM @inputxml.nodes('Lineitems/Lineitem') T(C)

请根据您在select语句中的要求更改变量数据类型,否则将是您的错误。

答案 1 :(得分:1)

您的代码有很多问题,我想算的不胜枚举。看起来它确实是从SQL Server 2000数据库移植而来,只是添加了一些最少的附加内容,例如try / catch块和max数据类型。

基本上,您的整个TRY可以用以下2条语句代替:

insert into dbo.TblTickerTemplate (LineItem, Ticker)
select t.c.value('(./LineItem/text())[1]', 'varchar(100)'),
  t.c.value('(./Ticker/text())[1]', 'varchar(100)')
from @inputxml.nodes('./Lineitems[1]/Lineitem[(./ID/text())[1] = "0"]') t(c);

insert into dbo.TblTickerTemplateDetail ([Action], LineItem, MasterTemplateID, UserID, XFundCode)
select case t.c.value('(./ID/text())[1]', 'int') when 0 then 'I' else 'U' end as [Action],
  t.c.value('(./LineItem/text())[1]', 'varchar(100)') as [LineItem],
  m.ID as [MasterTemplateId],
  t.c.value('(./UserID/text())[1]', 'varchar(20)') as [UserId],
  t.c.value('(./XFundCode/text())[1]', 'varchar(100)') as [XFundCode]
from dbo.TblTickerTemplate m
  inner join @inputxml.nodes('./Lineitems[1]/Lineitem') t(c) on
    m.LineItem = t.c.value('(./LineItem/text())[1]', 'varchar(100)')
    and m.Ticker = t.c.value('(./Ticker/text())[1]', 'varchar(100)');

并不是特别理想-对于大小合适的XML(100多个节点),通常最好先以关系形式缓存数据,要么将其存储在@table变量(它们已经存在于2000年,是的)中,要么存储在#temporary表中。另外,在第一个插入中,您将要添加存在检查,以使新插入的行不会破坏您的自然键。但是作为骨架,是的。

我注意到的另一件事是./UserID属性实际上从未使用过-您的代码将@UserID变量放入游标声明中,然后将变量(即NULL (此时)在fetch next中分配给自己。毫无疑问,有错字或复制粘贴。

答案 2 :(得分:0)

  

存储过程不会无误地添加任何数据

这是因为OPENXML只是返回NULL。

SELECT Ticker,ID,Lineitem,XFundCode,@UserID
FROM OPENXML (@XMLFORMAT, '/Lineitems', 1)
        WITH (
            Ticker                  VARCHAR(MAX),
            ID                      INT,
            Lineitem                VARCHAR(MAX),
            XFundCode               VARCHAR(MAX),
            UserID                  VARCHAR(MAX)
         );

应为:

SELECT Ticker,ID,Lineitem,XFundCode,@UserID
    FROM OPENXML (@XMLFORMAT, '/Lineitems/Lineitem', 2)
    WITH (
        Ticker                  VARCHAR(MAX),
        ID                      INT,
        Lineitem                VARCHAR(MAX),
        XFundCode               VARCHAR(MAX),
        UserID                  VARCHAR(MAX)
     )

请注意,将OPENXML的模式从 1(以属性为中心)更改为 2(以元素为中心),并将'/Lineitems'更改为{{1} }。

也:'/Lineitems/Lineitem'应该有相应的Exec sp_xml_preparedocument

总结:我同意你应该避免使用EXEC sp_xml_removedocument并使用sp_xml_preparedocument/OPENXML/CURSOR语法完全重写它的评论。

db<>fiddle demo