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

Sql server 具有多个输入变量(表值参数)的存储过程的实现,sql-server,tsql,stored-procedures,Sql Server,Tsql,Stored Procedures,对于一门课程,我尝试使用TSQL创建一个存储过程,它应该在我的DB中为可以在车辆上执行的各种服务创建一个服务票证。这些服务包括一般服务、维修和检查,以及一些有关成本的进一步信息。 因此,如果在执行过程后成功创建serviceticket,则应返回serviceticket编号 输入参数为: VehicleId, ticketDate, customerId, serviceTypes (TVP), repairs (TVP), inspections (TVP) 输出参数:ServiceTic

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

输入参数为:

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

旁注:您不应该在存储过程中使用
sp
前缀。微软已经这样做了,而且你确实有可能在将来的某个时候发生名称冲突。最好只是简单地避免使用
sp.
并使用其他东西作为前缀,或者根本不使用前缀!嗨@marc_谢谢。那么你想一次插入所有这些不同类型的门票吗?我不确定我是否遵循了这里的逻辑。似乎您应该能够在将数据插入ServiceTicket之前,使用连接来收集不同表中的数据,从而构建您的进程。但是在insert语句中,
@inspectionId
似乎是来自TVP
@InspectionType
的唯一数据。其他值与SP输入参数中的
@vehicleId
@serviceDate
@customerId
相关。您计划如何使用其他两个TVP(
@ServiceType
@RepairType
)您列出的表,它们是预定义的还是您定义的?
    INSERT INTO ServiceTicket 
    VALUES (@ticketIssueNo, @serviceDate, @vehicleId, @customerId, @inspectionId)

    SELECT *
    FROM @serviceType
    WHERE ...
END