创建多个记录的单记录视图的SQL查询-动态存储过程?

创建多个记录的单记录视图的SQL查询-动态存储过程?,sql,arrays,sql-server-2008,stored-procedures,Sql,Arrays,Sql Server 2008,Stored Procedures,好的,我想一定有一个更简单的方法来做这件事,我想动态地做,而不是手写每一行。与SQLServer2008相比,我更熟悉MySQL,但我也不确定在MySQL中如何做到这一点 我有三张桌子 Table 1: USER id | email | password Table 2: METADATA id | name (list of fields I need to know about user) Table 3: USER_META id | uid | name |

好的,我想一定有一个更简单的方法来做这件事,我想动态地做,而不是手写每一行。与SQLServer2008相比,我更熟悉MySQL,但我也不确定在MySQL中如何做到这一点

我有三张桌子

Table 1:  USER       id | email | password
Table 2:  METADATA   id | name   (list of fields I need to know about user)
Table 3: USER_META   id | uid | name | value (where I store the user meta data)
我不会硬编码元数据,因为它会针对此应用程序的每个实例进行更改。但在这个例子中,让我们只说元数据是“眼睛”、“电话”、“城市”(实际上还有很多,本周可能有20个,下周可能有40个)

因此,它的工作方式是当用户注册时,我使用元数据表来构建注册表单。它创造了一种有“眼睛”、“电话”和“城市”的形式

当我保存表单时,我将每个数据项的一条记录保存到
USER\u META
表中。 因此,注册时,我会收到3个插入:

  insert into USER_META(uid,name,value) values (5,"eyes","brown")
  insert into USER_META(uid,name,value) values (5,"phone","555-1212")
  insert into USER_META(uid,name,value) values (5,"city","San Francisco")
现在,我想编写一个存储过程,它将返回如下记录“

返回:

uid |  email  |  eyes | phone | city
5    x@x.com    brown   555-1212  San Francisco;
我可以写一个长的硬编码select语句,如:

DECLARE @UID int;
SELECT  id, email,  
(select value from USER_META
 where uid = @UID and name = 'EYES') as EYES,
(select value from USER_META
 where uid = @UID and name = 'PHONE') as PHONE,
(select value from USER_META
 where uid = @UID and name = 'CITY') as CITY,
FROM  USER 
where id = @UID;
但是这样做违背了整个目的,每当元数据需求发生变化时(例如,当我们启动另一个实例时),我每周都必须再次编写它

我希望有这样的东西:(请原谅,我对高级SQL不是很有经验,所以可能这很容易,我只是不知道怎么做?)我将用基本的代码术语来写它,试图解释我的想法:

DECLARE @UID int;
DECLARE @META_NAMES array;
@META_NAMES = (select NAME from METADATA);

SELECT  id, email,  
 for each (@META_NAMES as $THIS_NAME) {

  (select value from USER_META
   where uid = @UID and name = '$THIS_NAME') as $THIS_NAME,

}
FROM  USER 
where id = @UID;

有没有一种方法可以在SQL Server 2008中编写此代码?

您可以在SQL Server中使用XML\u路径。这是一种解决组\u CONCAT的方法

SELECT
    U.UID,
    U.EMAIL,
    stuff(
    (
    select cast(',' as varchar(max)) + name + '=' + Value
    from USER_META
    WHERE UID = U.UID
    for xml path('')
    ), 1, 1, '') AS M
FROM
    USERS U

Cha,谢谢,这是一个好的开始,我可以编写一些代码从M中提取所有名称/值对-这完全可以。有没有办法将名称转换为字段名?为此,您可以使用动态SQL。首先,您可以使用
select cast(','as varchar(max))提取名称+name来自USER_META,其中UID=5表示xml路径(“”)
然后使用构造的SQL将其传递给sp_execute存储过程更正:您将使用
从USER_META(其中UID=5表示xml路径(“”)
中选择cast(’,'as varchar(max))+value+'as['+name+']'表示xml路径(“”)这不是一个真正好的数据模型(google EAV)。出于兴趣,为什么要将其放在一行中?为什么不将每个元数据值放在一行中?@LoztInSpace我认为它比EAV更适合于行建模,-我确实有一个视图,可以按行返回所有元数据值。我正在创建报告,而我可以对元数据结果进行分组,并在报告中循环(最基本的方法是创建用户/元数据的电子表格)-我想构建一个动态查询来为我返回该查询结构,而不是用代码来提取。-这可能会产生误导,因为我遗漏了一些细节-元数据表也有一个“已启用”“切换-因此每个启用的名称/值对对于实例来说都是必不可少的,在USER_meta中没有一堆空的元数据对。
SELECT
    U.UID,
    U.EMAIL,
    stuff(
    (
    select cast(',' as varchar(max)) + name + '=' + Value
    from USER_META
    WHERE UID = U.UID
    for xml path('')
    ), 1, 1, '') AS M
FROM
    USERS U