具有多个输入变量(表值参数)的存储过程的实现

时间:2019-03-31 07:00:11

标签: sql-server tsql stored-procedures

对于一门课程,我尝试使用TSQL创建一个存储过程,该存储过程应在我的数据库中为可以在车辆上进行的各种服务创建服务票证。这些服务可以包括一般服务,维修和检查,以及有关成本的更多信息。 因此,如果在执行该过程后成功创建了服务票,则应返回服务票号。

输入参数为:

VehicleId, ticketDate, customerId, serviceTypes (TVP), repairs (TVP), inspections (TVP)

输出参数:ServiceTicket编号

数据库中的表:

CREATE TABLE dbo.StandardService
(
    serviceId CHAR(8) PRIMARY KEY NOT NULL,
    leaseNo CHAR(8) NOT NULL,
    serviceDate DATE NOT NULL,
    includesInspection CHAR(8) NOT NULL,
    serviceName VARCHAR(25) NOT NULL DEFAULT '',
    serviceDescription VARCHAR(50) NOT NULL DEFAULT '',
    currentPrice DECIMAL(8,4) NOT NULL CHECK(currentPrice BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,

    FOREIGN KEY(includesInspection) 
        REFERENCES VehicleInspection(inspectionId)
            ON DELETE NO ACTION,
    FOREIGN KEY(leaseNo) 
        REFERENCES VehicleLease(leaseNo)
            ON DELETE NO ACTION
)

CREATE TABLE dbo.VehicleInspection
(
    inspectionId CHAR(8) PRIMARY KEY NOT NULL,
    inspectionName VARCHAR(25) NOT NULL DEFAULT '',
    currentPrice DECIMAL(8,4) NOT NULL DEFAULT 0.0,
    vehicleTypeId CHAR(8) NOT NULL DEFAULT '',

    FOREIGN KEY (vehicleTypeId) 
        REFERENCES VehicleType(vehicleTypeId)
            ON UPDATE CASCADE ON DELETE NO ACTION
) 

CREATE TABLE dbo.VehicleRepair
(
    vehicleRepairId CHAR(8) NOT NULL,
    vehiclePrvId CHAR(8),
    vehiclePurchId CHAR(8),
    ticketIssueNo CHAR(8),
    labourCost DECIMAL(8,4) NOT NULL CHECK(labourCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
    partCost DECIMAL(8,4) NOT NULL CHECK(partsCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,

    PRIMARY KEY(vehicleRepairId),

    FOREIGN KEY(vehiclePrvId) 
        REFERENCES VehiclePrevLeased(vehicleId)
            ON DELETE NO ACTION,
    FOREIGN KEY(vehiclePurchId) 
        REFERENCES VehiclePurchased(vehicleId)
            ON DELETE NO ACTION,
    FOREIGN KEY(ticketIssueNo) 
        REFERENCES ServiceTicket(ticketIssueNo)
            ON DELETE NO ACTION
)

CREATE TABLE dbo.ServiceTicket
(
    ticketIssueNo CHAR(8) PRIMARY KEY NOT NULL,
    serviceDate DATE NOT NULL,
    vehicleId CHAR(8) NOT NULL,
    customerId CHAR(8) NOT NULL,
    inspectionId CHAR(8) NOT NULL,
    serviceCost DECIMAL(8,4) NOT NULL CHECK(serviceCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
    inspectionCost DECIMAL(8,4) NOT NULL CHECK(inspectionCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
    repairCost DECIMAL(2,2) NOT NULL CHECK(repairCost BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,
    GST DECIMAL(8,4) NOT NULL DEFAULT 0.0,
    amountDue DECIMAL(8,4) NOT NULL CHECK(amountDue BETWEEN 0.0 AND 99999.0) DEFAULT 0.0,

    FOREIGN KEY(vehicleId) 
         REFERENCES Vehicle(vehicleId)
            ON UPDATE NO ACTION,
    FOREIGN KEY(inspectionId) 
         REFERENCES VehicleInspection(inspectionId)
            ON UPDATE NO ACTION,
    FOREIGN KEY(customerId) 
         REFERENCES Customer(customerId)
            ON UPDATE NO ACTION,
)

我以前没有存储过程方面的经验,也找不到与这个更复杂的问题相关的好例子。到目前为止,我为TVP值创建了三个表。

三种服务类型的类型

CREATE TYPE ServiceType AS TABLE
(
    serviceId CHAR(8),
    PRIMARY KEY(serviceId) 
)

CREATE TYPE RepairType AS TABLE
(
    vehicleRepairId CHAR(8),
    PRIMARY KEY(vehicleRepairId) 
)

CREATE TYPE InspectionType AS TABLE
(
    inspectionId CHAR(8),
    PRIMARY KEY(inspectionId) 
)

-- Creating stored proc with input parameter to receive data 
-- for the table-valued parameter

CREATE PROCEDURE usp_GenerateServiceTicket 
    @vehicleId CHAR(8),
    @serviceDate DATE,
    @customerId CHAR(8),
    @gst DECIMAL(8,4),
    @serviceType ServiceType READONLY,
    @repairType RepairType READONLY,
    @inspectionType InspectionType READONLY,
-- output parameter for stored procedure
    @ticketIssueNo CHAR(8) OUTPUT  
AS
BEGIN
    SET NOCOUNT ON;

    -- How to continue in this case when multiple information needs to be retrieved first 

从各种表开始,然后才能将其插入

ServiceTicket表以创建新的Service Ticket

    INSERT INTO ServiceTicket 
    VALUES (@ticketIssueNo, @serviceDate, @vehicleId, @customerId, @inspectionId)

    SELECT *
    FROM @serviceType
    WHERE ...
END

在这种情况下,如果我需要查询数据库中的多个表,收集所有返回的信息并将其插入ServiceTicket,该如何构造该过程?非常感谢您的任何提示/帮助。

0 个答案:

没有答案