执行带输出参数的存储过程为什么需要空值?

问题描述 投票:0回答:1

我正在使用 SQL Server 中的 AdventureWorks2019 数据库制作一个 ERP 程序用于练习,并且一个带有输出参数的存储过程无法正常运行,除非我将其值指定为 null,而其他类似的过程则没有这样的问题。为什么?其他程序是否有问题?使用输出参数在语法上执行程序的教科书方式是什么?还有什么建议吗?

drop procedure if exists sohead; 

create procedure sohead
    @BusinessEntityid int,                      
    @customerid int,                        
    @persontype nchar(2) output,        
    @storeid int output,                    
    @orderdate datetime output,             
    @duedate datetime output,               
    @accountnumber nvarchar(15) output,     
    @salespersonid int output,              
    @territoryid int output,            
    @billToAddressid int output,    
    @shipToAddressid int output,    
    @shipMethodid int,  
    @creditcardid int output,   
    @currencyrateid int =null,     
    @subtotal money, 
    @taxamt money,    
    @freight money,     
    --totaldue self generated and computed
    @comment nvarchar(128)  
AS
BEGIN 
    set nocount on;
        begin try
        
            begin transaction
            --@storeid
            
                select @storeid = storeid from sales.customer where CustomerID = @customerid;

            --orderdate 
            SET @orderdate = GETDATE();
            --duedate
            SET @duedate = DATEADD(day, 15, @orderdate);

            --salespersonid
            
            if @storeid IS NULL
                SET @salespersonid = NULL;
            else
                SELECT @salespersonid = SalesPersonID 
                FROM Sales.Store 
                WHERE BusinessEntityID = @storeid;

            --territoryid
            select @territoryid = territoryid from sales.Customer
            where customerid = @customerid;

            --biiltoaddress  AND  shipaddressid
            --;WITH persontypecte AS (
            --      SELECT persontype 
            --      FROM person.Person
            --      WHERE BusinessEntityID = @businessentityid
            --  )
            --select @persontype = persontype from persontypecte
            select @persontype = persontype FROM person.Person
                    WHERE BusinessEntityID = @businessentityid;

            if @persontype = 'SC' 
            BEGIN
                        ;with billshipadd as(
                            SELECT AddressID FROM  
                            person.BusinessEntityAddress

                            where BusinessEntityid = @storeid
    
                        )
                        select   @BILLTOADDRESSID = addressid,@SHIPTOADDRESSID = addressid  from billshipadd; --address GIA 'SC'
            
            END
            ELSE IF @PERSONTYPE = 'IN' 
            BEGIN
                        ;with billshipadd as(
                            SELECT AddressID FROM  
                            person.BusinessEntityAddress

                            where BusinessEntityid = @businessentityid
    
                        )
                        select   @BILLTOADDRESSID = addressid,@SHIPTOADDRESSID = addressid  from billshipadd; --address gia 'IN'
            END;             

            --creditcardid

            select @creditcardid =  CreditCardID from Sales.PersonCreditCard where businessentityid = @BusinessEntityid;

            --accountnumber 

            select @accountnumber = accountnumber from sales.customer where customerid = @customerid;

            --currencyrateid

            --null


            insert into sales.salesorderheader(revisionNumber, orderdate, duedate, shipdate, status,
            onlineorderflag, purchaseordernumber, accountnumber, customerid, salespersonid, territoryid,        
    billtoaddressid, shiptoaddressid, shipmethodid, creditcardid, creditcardapprovalcode,       
    currencyrateid, subtotal, taxamt, freight, comment, rowguid, modifieddate)
            VALUES(
            0,
            @orderdate,
            @duedate,
            null,
            1,
            0,
            null,
            @accountnumber,
            @customerid,
            @salespersonid,
            @territoryid,
            @billToAddressid,
            @shipToAddressid,
            @shipMethodid,
            @creditcardid,
            null, --credit card approval code
            @currencyrateid,
            @subtotal,
            @taxamt,
            @freight,
            --@totaldue, --mono toy
            @comment,
            newid(),
            getdate()
    );

            commit transaction
        end try
        begin catch 
            SELECT
                ERROR_NUMBER() AS ErrorNumber,
                ERROR_SEVERITY() AS ErrorSeverity,
                ERROR_STATE() AS ErrorState,
                ERROR_MESSAGE() AS ErrorMessage;

        IF @@TRANCOUNT > 0
            rollback transaction;
            throw;
        end catch
end;
                 
exec sohead @businessentityid=1983 , @customerid=30113 ,@shipmethodid= 1, @subtotal =5,
@taxamt =5, @freight = 5, @comment = null,@persontype = null, @storeid = null,@orderdate = null, @duedate = null, @accountnumber= null, @salespersonid= null,
@territoryid = null, @billToAddressid = null, @shipToAddressid=null, @creditcardid = null;

显然这是执行它的正确方法 但我认为这已经足够了:

exec sohead @businessentityid=1983 , @customerid=30113 ,@shipmethodid= 1, @subtotal =5,
@taxamt =5, @freight = 5;
sql sql-server stored-procedures
1个回答
0
投票

OUTPUT
参数为still输入参数;有仅输入和输入/输出参数,没有仅输出参数。如果您没有为参数分配默认值,则在省略该参数时,您在执行过程时必须提供该参数。

您的

OUTPUT
参数没有默认值,与您的参数
@currencyrateid
不同,因此您必须提供一个值,可以
NULL

© www.soinside.com 2019 - 2024. All rights reserved.