验证不适用于where子句中的参数和强制转换

时间:2016-08-30 13:54:57

标签: sql sql-server tsql

我在尝试执行下面的过程时遇到了一个小问题:

exec SupportAudit.BI.CreateMCCInvoiceReversal 'APCCP/000', 29923

我在proc中有一段代码,用于检查发票编号是否已存在:

        -- see if invoice number already exisits
if exists (select 1 from Jet2Fees.Discount.Invoice where InvoiceNumber = @InvoiceNumber + '/' +  cast(@InvoiceID as varchar(50)))
            BEGIN;
                set @errormsg = 'Invoice Number already exists';
                THROW 99999, @errormsg, 1
            END;

目前,即使发票编号存在,它仍然会插入一行。如果我将where InvoiceNumber = @InvoiceNumber + cast(InvoiceID as varchar)替换为where InvoiceNumber = 'APCCP/00029923'。验证工作正常。所以我的问题是为什么当我使用InvoiceNumber = @InvoiceNumber + cast(InvoiceID as varchar)的地方时它现在有效?这条线应该是什么?

以下是proc的代码:

    ALTER Procedure [BI].[CreateMCCInvoiceReversal]
    (

        @InvoiceNumber      varchar(255),
        @InvoiceId          int,
    )
    AS

    /**
    ** Script to create MCC Invoice Reversal
    **
    ** Table(s) updated: Discount.Invoice
    **
    ** Version 1.0 - MKP - 25/08/2016 - Written
    **
    **/

    BEGIN

    SET NOCOUNT ON;
    SET XACT_ABORT ON;

    declare @errormsg           varchar(250);
    declare @OutputList         [Core].[RollbackOutputList];
    declare @CountRows          int;

    Set @procname = OBJECT_NAME(@@ProcID)

    BEGIN TRY

    BEGIN TRAN MCCInvoiceReversal

            INSERT INTO [Jet2Fees].Discount.Invoice
                    (
                    InvoiceNumber,
                    )

            OUTPUT '[Jet2Fees].Discount.Invoice', 'InvoiceID', inserted.InvoiceId,
                                    Core.insXMLFragment('InvoiceId')+Core.addnlXMLFragment('InvoiceId', inserted.InvoiceId)


                INTO @OutputList

                SELECT @InvoiceNumber  +  cast(InvoiceID as varchar),
                FROM Jet2Fees.Discount.Invoice
                WHERE InvoiceId = @InvoiceId

                if( @@ROWCOUNT <> 1)
                    BEGIN
                    ROLLBACK TRAN MCCInvoiceReversal
                    set @errormsg = 'Record not found, please check details entered';
                    THROW 99999, @errormsg, 1
                    END

        --see if invoice number already exists
if exists (select 1 from Jet2Fees.Discount.Invoice where InvoiceNumber = @InvoiceNumber + '/' +  cast(@InvoiceID as varchar(50)))
            BEGIN;
                set @errormsg = 'Invoice Number already exists';
                THROW 99999, @errormsg, 1
            END;

    exec Core.insertRollbackXML @outputList, @TaskLogid, @procname

    COMMIT TRANSACTION MCCInvoiceReversal

    END TRY

2 个答案:

答案 0 :(得分:1)

假设参数具有以下值

@InvoiceNumber ='APCCP/000'
@InvoiceId = 29923

现在看看你在where子句

中做错了什么
where InvoiceNumber = @InvoiceNumber + '/' +  cast(@InvoiceID as varchar(50))

那是@InvoiceNumber + '/' + cast(@InvoiceID as varchar(50))此字符串的输出类似于'APCCP/000/29923',你的where条件会变成这样

where InvoiceNumber = 'APCCP/000/29923'

据我所知,唯一的理由就是你的查询失败了。在不使用/

的条件下尝试此操作
WHERE InvoiceNumber = @InvoiceNumber  +  cast(@InvoiceID as varchar(50))

答案 1 :(得分:0)

使用以下脚本..

select @CountRows = count(*)
      from Jet2Fees.Discount.Invoice
      where InvoiceNumber = Ltrim(rtrim(@InvoiceNumber)) + LTRIM (rtrim (cast(@InvoiceID as varchar(50))))-- should match with the max length of your invoice id


      if        @CountRows >= 1
            begin
                ROLLBACK TRAN MCCInvoiceReversal
                set @errormsg = 'Invoice Number already exists';
                THROW 99999, @errormsg, 1
            end