2016-09-16 42 views
0

我正在研究动态查询,该查询允许我在数据库表中定义字段类型,然后提取在创建仪表板时选择的用户定义字段的列表以及为每个逻辑选择的值运营商。TSQL有条件加入声明?

例如,使用可以选择field1这就是employeeID。然后他们可以提供他们想要搜索的ID,并且它将在我们需要呈现数据时将fieldIDfieldValue存储在表中。

现在取决于所选择的字段,我可能需要加入另一个表以获取更多信息,例如员工姓名。

虽然这很简单,但棘手的部分发挥作用时,必须加入对多个可能的表的值。如果我存储employeeID,我会将该字段与雇员表一起加入。但是,如果我存储了storeID,则需要将该字段与stores表结合起来。

这是我在结束之前的想法,意识到自己被卡住了。基本上,我会说:“如果这个领域是一个人表isPeople=1然后加入我们的employeeTable

如果该字段isTool=1,加入我们的工具表。

我基本上是有一个fieldTypefieldValue和基于类型,我需要加入一个特定表上我已经存储的值。

enter image description here

当我通过这使其动态sql的工作,我意识到,我不能使用fl.*字段创建我的IF条件。

即。 IF (fl.isPeople =1) BEGIN ... JOIN Employee Table ... END

我认为采取动态的方法将是唯一的方法来做到这一点,但现在我想不出解决我的问题。

在结论...

我想加入基于条件的表和查询字段。由于我似乎无法在我的普通存储过程中执行此操作,因此我试图动态执行此操作,并最终在此处解决,这是我试图解释的非常混乱的问题。

让我知道我是否可以进一步澄清。

更新:

USE [red] 
GO 
/****** Object: StoredProcedure [dbo].[ti2_fetch_dashboard] Script Date: 9/15/2016 9:55:39 PM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  Carl 
-- Create date: Sept 13, 2016 
-- Description: Fetch Single Dashboard for Editing 
-- ============================================= 
ALTER PROCEDURE [dbo].[ti2_fetch_dashboard_test] 
@dashboardID INT, @SQL NVARCHAR(MAX) = '' 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Fetch our dashboard 
    SELECT @SQL = 'SELECT d.dashboardID, 
      d.dashboardOwner, 
      e.PreferredName AS ownerFirst, 
      e.LastName AS ownerLast, 
      e.NTID AS ownerNTID, 
      d.dashboardTitle, 
      d.dashboardDescription, 
      d.dashboardType, 
      d.creator, 
      d.timestamp, 
      d.lastUpdate, 
      d.isDeleted, 
      (SELECT sub.QID AS subscriberQID, 
        e.PreferredName AS subscriberFirst, 
        e.LastName AS subscriberLast, 
        e.NTID AS subscriberNTID 
      FROM dbo.ti_dashboard_subscribers AS sub 
        LEFT OUTER JOIN 
        dbo.EmployeeTable AS e 
        ON sub.QID = e.QID 
      WHERE sub.dashboardID = d.dashboardID 
      FOR XML PATH (''options''), ELEMENTS, TYPE, ROOT (''subscribers'')), 
      (SELECT f.fid, 
        f.fieldID, 
        f.[order], 
        cfg.primaryAllowed, 
        cfg.secondaryAllowed, 
        cfg.exportAllowed, 
        mf.fieldName, 
        mf.placeholder 
      FROM  dbo.ti_dashboards_fields AS f 
        INNER JOIN 
        dbo.ti_dashboard_field_types AS ft 
        ON f.typeID = ft.fieldTypeID 
        INNER JOIN 
        dbo.ti_dashboard_master_fields_config AS cfg 
        ON f.fieldID = cfg.fieldID 
        INNER JOIN 
        dbo.ti_dashboards_master_fields AS mf 
        ON mf.fieldID = f.fieldID 
      WHERE f.dashboardID = d.dashboardID 
        AND ft.fieldTypeName = ''Primary'' 
      ORDER BY f.[order] ASC 
      FOR  XML PATH (''fields''), ELEMENTS, TYPE, ROOT (''primaryFields'')), 
      (SELECT f.fid, 
        f.fieldID, 
        f.[order], 
        cfg.primaryAllowed, 
        cfg.secondaryAllowed, 
        cfg.exportAllowed, 
        mf.fieldName, 
        mf.placeholder 
      FROM  dbo.ti_dashboards_fields AS f 
        INNER JOIN 
        dbo.ti_dashboard_field_types AS ft 
        ON f.typeID = ft.fieldTypeID 
        INNER JOIN 
        dbo.ti_dashboard_master_fields_config AS cfg 
        ON f.fieldID = cfg.fieldID 
        INNER JOIN 
        dbo.ti_dashboards_master_fields AS mf 
        ON mf.fieldID = f.fieldID 
      WHERE f.dashboardID = d.dashboardID 
        AND ft.fieldTypeName = ''Secondary'' 
      ORDER BY f.[order] ASC 
      FOR  XML PATH (''fields''), ELEMENTS, TYPE, ROOT (''secondaryFields'')), 
      (SELECT f.fid, 
        f.fieldID, 
        f.[order], 
        cfg.primaryAllowed, 
        cfg.secondaryAllowed, 
        cfg.exportAllowed, 
        mf.fieldName, 
        mf.placeholder 
      FROM  dbo.ti_dashboards_fields AS f 
        INNER JOIN 
        dbo.ti_dashboard_field_types AS ft 
        ON f.typeID = ft.fieldTypeID 
        INNER JOIN 
        dbo.ti_dashboard_master_fields_config AS cfg 
        ON f.fieldID = cfg.fieldID 
        INNER JOIN 
        dbo.ti_dashboards_master_fields AS mf 
        ON mf.fieldID = f.fieldID 
      WHERE f.dashboardID = d.dashboardID 
        AND ft.fieldTypeName = ''Export'' 
      ORDER BY f.[order] ASC 
      FOR  XML PATH (''fields''), ELEMENTS, TYPE, ROOT (''exportFields'')), 
      (SELECT l.[fieldID], 
        -- Get the details of each of those fields 
        (SELECT fl.queryField, 
          fl.allowMultiple, 
          fl.isPeople, 
          fl.isDate, 
          fl.isSelect, 
          fl.isInput, 
          fl.isTool, 
          fl.selectOptions, 
          -- Get the values associcated with the fields 
          (SELECT dv.value'; 

          -- If fl.isPeople = 1 
          SELECT @SQL += ', e.PreferredName AS FirstName, e.LastName, e.NTID, e.QID '; 

          -- If fl.isTool = 1 
          SELECT @SQL += ', t.toolName, t.toolType '; 

          -- Primary Table 
          SELECT @SQL += 'FROM dbo.ti_dashboards_logic AS dv '; 

          -- If fl.isPeople = 1 
          SELECT @SQL += 'LEFT OUTER JOIN dbo.EmployeeTable AS e ON dv.value = e.QID '; 

          -- If fl.isTool = 1 
          SELECT @SQL += 'LEFT OUTER JOIN ti_tools AS t ON dv.value = t.tool '; 

          -- Rest of Statement 
          SELECT @SQL += 'WHERE dv.fieldID = l.fieldID 
            AND dv.dashboardID = d.dashboardID 
           FOR XML PATH (''data''), TYPE, ELEMENTS, ROOT (''values'')) 
         FROM dbo.ti_dashboard_master_fields_config AS fl 
         WHERE fl.fieldID = l.fieldID 
          AND l.dashboardID = d.dashboardID 
         FOR XML PATH (''fields''), TYPE, ELEMENTS, ROOT (''logicMeta'')) 
      FROM  [red].[dbo].[ti_dashboards_logic] AS l 
      WHERE l.dashboardID = d.dashboardID 
      GROUP BY l.fieldID, l.dashboardID 
      FOR  XML PATH (''fields''), TYPE, ELEMENTS, ROOT (''logicFields'')), 
      (SELECT sdb.dashboardID , 
         sdb.fieldID , 
         sdb.sort , 
         sdb.[order] , 
         mf.fieldName 
       FROM dbo.ti_dashboards_sorting AS sdb 
       JOIN dbo.ti_dashboard_master_fields_config AS sf 
       ON sdb.fieldID = sf.fieldID 
       JOIN dbo.ti_dashboards_master_fields AS mf 
       ON sf.fieldID = mf.fieldID 
       WHERE sdb.dashboardID = d.dashboardID 
       ORDER BY sdb.[order] ASC 
       FOR XML PATH (''fields''), TYPE, ELEMENTS, ROOT (''sortingFields'') 
      ) 
    FROM dbo.ti_dashboards AS d 
      LEFT OUTER JOIN 
      dbo.EmployeeTable AS e 
      ON d.dashboardOwner = e.QID 
    WHERE d.dashboardID = @_dashboardID 
      AND d.isDeleted = 0 
    FOR XML PATH (''data''), ELEMENTS, TYPE, ROOT (''root'')'; 

    EXEC sp_executesql @SQL, N'@_dashboardID INT', @_dashboardID = @dashboardID 

END 
+0

发布您的代码 – Amit

+0

我认为您可能会从使用ORM工具获益,因此您可以在代码层中进行更多动态查询,或者可以使用多个查询并在几次旅行中提取数据数据库而不是试图一次性完成这一切....我一直在走你要走的道路,做动态动态查询并不是一条好路径。如果你的数据集有点大,你很快就会遇到性能问题。 –

+0

你是否也可以提供所有的字段给用户,并保留空白('NULL')并检查连接条件?这样,您可以始终加入所有表格,但仅限于使用的参数。 – NickyvV

回答

0

您不能加入动态表通过数据和不同数量的每一行的列驱动。

你只需要使用UNION来合并来自多个SELECT查询的结果。每个SELECT查询都会有不同的连接和WHERE语句(isPeople,isTool等)。

或者你可以加入所有相关表格并在声明中像添加更多的条件,下面的伪代码:

SELECT e.xxxx, t.yyyy, dv.zzzz, fl.ffff 
FROM dbo.ti_dashboards_logic AS dv 
    JOIN dbo.ti_dashboard_master_fields_config AS fl ON .... 
    LEFT OUTER JOIN dbo.EmployeeTable AS e ON dv.value = e.QID AND fl.isPeople = 1 
    LEFT OUTER JOIN ti_tools AS t ON dv.value = t.tool AND fl.isTool = 1 

所以每行有相同的列数,并t.yyyy和e.xxxx会根据fl.isTool和fl.isPeople值,为NULL或不为NULL。

+0

你可能会提供一些伪代码给你建议? – SBB

+0

更新了我的答案。代码太大,难以阅读。您需要使用临时表或表变量将其拆分为多个部分。 – Anton