如何从 EAV 数据模型中检索多个项目及其所有属性?
How to retrieve multiple items with all their attributes from an EAV data model?
有人如何检索多个产品及其所有属性,这些产品的 ID 作为逗号分隔列表传递给存储过程?
表格以简单的 EAV 方式设计,如下所示:
tbl_products
id
title
tbl_product_attributes
product_FK
attribute_FK
attribute_value
tbl_attributes
id
title
以下存储过程仅针对一种产品执行此操作:
CREATE PROCEDURE get_product
@product_id NVARCHAR(MAX)
AS
BEGIN
-- Create a temp table to store values of get_product_attributes sp
CREATE TABLE #temp ( attributes NVARCHAR(MAX) );
-- Insert results of get_product_attributes sp into temp table
INSERT INTO #temp (attributes)
EXEC get_product_attributes @product_id;
-- Select product with all its attributes
SELECT id,
title,
( SELECT attributes FROM #temp ) AS attributes
FROM tbl_products
WHERE id = @product_id;
END;
但是如果我们想要给定产品 ID 的多个产品详细信息怎么办?
(get_product_attributes 存储过程 return 特定产品的所有属性及其值 json 它使用动态 sql 检索所有属性然后 return 它们作为 json;完全像这个答案的动态 sql 部分所做的那样:)
(也使用 sql 服务器 2016,可以访问 STRING_SPLIT 函数并且可以轻松地将传递的 ID 转换为行)
一般来说,SQL 中的循环不好。对于您所描述的内容,我无法想象为什么会出现循环。但是,这是一个基于集合的方法,具有简单的连接,可以消除除单个过程之外的所有内容。
declare @tbl_products table (
id int,
title varchar(16))
insert into @tbl_products
values
(1,'prod1'),
(2,'prod2'),
(3,'prod3'),
(4,'prod4'),
(5,'prod5')
declare @tbl_attributes table (
id int,
title varchar(16))
insert into @tbl_attributes
values
(1,'attr1'),
(2,'attr2'),
(3,'attr3'),
(4,'attr4'),
(5,'attr5')
declare @tbl_product_attributes table (
product_FK int,
attribute_FK int,
attribute_value varchar(64))
insert into @tbl_product_attributes
values
(1,5,'blah'),
(1,3,'blah blah'),
(2,1,'not sure'),
(2,3,'what should be here'),
(2,4,'but here is a'),
(3,5,'line of text'),
(3,4,'as a place holder')
declare @product_id nvarchar(4000)
set @product_id = '1,3'
if object_id ('tempdb..#staging') is not null
drop table #staging
select
prod.id
,prod.title as ProductTitle
,'Attr' + cast(attr.id as char(8)) as AttributeID
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
into #staging
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(@product_id,',') x
on x.value = prod.id
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME(AttributeID)
FROM (SELECT DISTINCT AttributeID FROM #staging) AS AttributeID
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'
SELECT ProductTitle, ' + @ColumnName + '
FROM #staging
PIVOT(min(AttributeTitle)
FOR AttributeID IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery
因此,您只需在顶部创建过程...
create proc yourProc(@product_id nvarchar(4000))
as
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
where
prod.id in (select * from string_split(@product_id,','))
注意:这也可以更干净地写成 join
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(@product_id,',') x
on x.value = prod.id
有人如何检索多个产品及其所有属性,这些产品的 ID 作为逗号分隔列表传递给存储过程?
表格以简单的 EAV 方式设计,如下所示:
tbl_products
id
title
tbl_product_attributes
product_FK
attribute_FK
attribute_value
tbl_attributes
id
title
以下存储过程仅针对一种产品执行此操作:
CREATE PROCEDURE get_product
@product_id NVARCHAR(MAX)
AS
BEGIN
-- Create a temp table to store values of get_product_attributes sp
CREATE TABLE #temp ( attributes NVARCHAR(MAX) );
-- Insert results of get_product_attributes sp into temp table
INSERT INTO #temp (attributes)
EXEC get_product_attributes @product_id;
-- Select product with all its attributes
SELECT id,
title,
( SELECT attributes FROM #temp ) AS attributes
FROM tbl_products
WHERE id = @product_id;
END;
但是如果我们想要给定产品 ID 的多个产品详细信息怎么办?
(get_product_attributes 存储过程 return 特定产品的所有属性及其值 json 它使用动态 sql 检索所有属性然后 return 它们作为 json;完全像这个答案的动态 sql 部分所做的那样:)
(也使用 sql 服务器 2016,可以访问 STRING_SPLIT 函数并且可以轻松地将传递的 ID 转换为行)
一般来说,SQL 中的循环不好。对于您所描述的内容,我无法想象为什么会出现循环。但是,这是一个基于集合的方法,具有简单的连接,可以消除除单个过程之外的所有内容。
declare @tbl_products table (
id int,
title varchar(16))
insert into @tbl_products
values
(1,'prod1'),
(2,'prod2'),
(3,'prod3'),
(4,'prod4'),
(5,'prod5')
declare @tbl_attributes table (
id int,
title varchar(16))
insert into @tbl_attributes
values
(1,'attr1'),
(2,'attr2'),
(3,'attr3'),
(4,'attr4'),
(5,'attr5')
declare @tbl_product_attributes table (
product_FK int,
attribute_FK int,
attribute_value varchar(64))
insert into @tbl_product_attributes
values
(1,5,'blah'),
(1,3,'blah blah'),
(2,1,'not sure'),
(2,3,'what should be here'),
(2,4,'but here is a'),
(3,5,'line of text'),
(3,4,'as a place holder')
declare @product_id nvarchar(4000)
set @product_id = '1,3'
if object_id ('tempdb..#staging') is not null
drop table #staging
select
prod.id
,prod.title as ProductTitle
,'Attr' + cast(attr.id as char(8)) as AttributeID
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
into #staging
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(@product_id,',') x
on x.value = prod.id
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE @ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME(AttributeID)
FROM (SELECT DISTINCT AttributeID FROM #staging) AS AttributeID
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'
SELECT ProductTitle, ' + @ColumnName + '
FROM #staging
PIVOT(min(AttributeTitle)
FOR AttributeID IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery
因此,您只需在顶部创建过程...
create proc yourProc(@product_id nvarchar(4000))
as
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
where
prod.id in (select * from string_split(@product_id,','))
注意:这也可以更干净地写成 join
select
prod.id
,prod.title as ProductTitle
,attr.title as AttributeTitle
,prodAttributes.attribute_value as EAV_AttributeValue
from
@tbl_products prod
inner join
@tbl_product_attributes prodAttributes
on prodAttributes.product_FK = prod.id
inner join
@tbl_attributes attr on
attr.id = prodAttributes.attribute_FK
inner join
string_split(@product_id,',') x
on x.value = prod.id