我觉得我需要通过说我对SQL的知识非常有限来开始这个问题,因此我试图实现的解决方案来自于大量的阅读和缺乏经验。因此,如果我要求的是完成任务的错误方法,请相应地提出建议(而不是接受我必须有一些有效的理由来创建可能非常奇怪的SQL语句)。
问题
我有两个表Rooms
和RoomPhotoUrls
我在表值参数(TVP)中接收这些表的数据。 TVP可以有 n 房间,每个房间可以有 n 图像。我希望能够插入所有房间,然后获取插入的每个房间的ID,以便我可以插入图像并将它们关联到正确的房间
为什么我选择将此作为潜在的解决方案
从房间表中可以看出,它是另一个桌子的孩子(属性)。属性表还有其他要填充的表,所以我想通过我的property
对象对数据库进行一次调用,并让SQL管理所有数据插入\更新,而不是多次往返。
对SQL的了解有限,我做了很多阅读,发现TVP似乎是我需要使用的。我还读到了关于传递xml
参数的信息,但我觉得传递xml
只是一个解决方案,因为没有引入TVP,所以我选择了TVP选项。
我添加的代码
您将在下面看到以下内容:
表架构
CREATE TABLE [dbo].[RoomPhotoUrls]
(
[RoomPhotoUrlsId] [int] IDENTITY(1,1) NOT NULL,
[RoomId] [int] NULL,
[Url] [varchar](max) NULL,
CONSTRAINT [PK_RoomPhotoUrls]
PRIMARY KEY CLUSTERED ([RoomPhotoUrlsId] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
CREATE TABLE [dbo].[Rooms]
(
[RoomId] [int] NULL,
[PropertyId] [int] NULL,
[RoomName] [varchar](120) NULL,
[RoomDescription] [varchar](max) NULL,
[RoomLength] [decimal](5, 2) NULL,
[RoomWidth] [decimal](5, 2) NULL,
[Url] [varchar](max) NULL
CONSTRAINT [PK_Rooms]
PRIMARY KEY CLUSTERED ([RoomId] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
表值参数
CREATE TYPE [dbo].[RoomTableType] AS TABLE(
[RoomId] [int] NULL,
[PropertyId] [int] NULL,
[RoomName] [varchar](120) NULL,
[Url] [varchar](max) NULL
)
示例数据
USE MyDb
DECLARE @roomTableType as RoomTableType
INSERT INTO @roomTableType ([RoomName], [Url])
VALUES ('Room 1', 'Url1'), ('Room 1', 'Url2'),
('Room 2', 'Url3'), ('Room 2', 'Url4'),
('Room 3', 'Url5'), ('Room 3', 'Url6'),
('Room 3', 'Url7')
EXEC dbo.phsp_CreatePropertyRooms @roomTableType, 1212
结果
房间
RoomId PropertyId RoomName RoomDescription RoomLength RoomWidth
---------------------------------------------------------------------
1259 1212 Room 3 test 1.00 1.00
1258 1212 Room 2 test 1.00 1.00
1257 1212 Room 1 test 1.00 1.00
RoomPhotoUrls
RoomPhotoUrlsId RoomId Url
----------------------------
1290 1257 Url7
1289 1257 Url6
1288 1257 Url5
1287 1257 Url4
1286 1257 Url3
1285 1257 Url2
1284 1257 Url1
我的存储过程
USE MyDb
GO
/****** Object: StoredProcedure [dbo].[phsp_CreatePropertyRooms] Script Date: 21/02/2018 23:02:24 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Tony Simpson
-- Create date: 04/12/17
-- Description: Create the rooms and images associated
-- =============================================
ALTER PROCEDURE [dbo].[phsp_CreatePropertyRooms]
@roomsTableType [dbo].[RoomTableType] READONLY,
@propertyId INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE @distinctRooms TABLE ([RoomId] int, [RoomName] varchar(120), [RoomDescription] varchar(MAX), [RoomLength] decimal, [RoomWidth] decimal)
DECLARE @insertedRooms TABLE ([RoomId] int, [RoomName] varchar(120), [RoomDescription] varchar(MAX), [RoomLength] decimal, [RoomWidth] decimal)
DECLARE @roomsTableTypeCopy TABLE ([RoomId] int, [RoomName] varchar(120), [RoomDescription] varchar(MAX), [RoomLength] decimal, [RoomWidth] decimal, [Url] Varchar(MAX))
--get distinct rooms
INSERT INTO @distinctRooms (RoomName, RoomDescription, RoomLength, RoomWidth)
SELECT DISTINCT
r.RoomName
,r.RoomDescription
,r.RoomLength
,r.RoomWidth
FROM @roomsTableType r
--insert into rooms table and save details in @insertedRooms
INSERT INTO Rooms (RoomName, RoomDescription, RoomLength, RoomWidth, PropertyId)
OUTPUT inserted.RoomId, inserted.RoomName, inserted.RoomDescription, inserted.RoomLength, inserted.RoomWidth INTO @insertedRooms
SELECT RoomName,
RoomDescription,
RoomLength,
RoomWidth,
@propertyId
FROM @distinctRooms
--populate @propertyTableTypeCopy so it can be updated
INSERT INTO @roomsTableTypeCopy (
[RoomId]
,[RoomName]
,[RoomDescription]
,[RoomLength]
,[RoomWidth]
,[url])
SELECT RoomId
,RoomName
,RoomDescription
,RoomLength
,RoomWidth
,[Url]
FROM @roomsTableType
--update rooms in @propertyTableTypeCopy with room id
UPDATE @roomsTableTypeCopy
SET [RoomId] = SR.RoomId
FROM @insertedRooms SR
CROSS APPLY (
SELECT [RoomId]
,[RoomName]
,[RoomDescription]
,[RoomLength]
,[RoomWidth]
FROM @insertedRooms
WHERE SR.RoomName = RoomName
AND SR.RoomLength = RoomLength
AND SR.RoomDescription = RoomDescription
AND SR.RoomWidth = RoomWidth
) AS r;
--add to table
INSERT INTO RoomPhotoUrls (RoomId, [Url])
SELECT [RoomId], [url]
FROM @roomsTableTypeCopy
END