我正在开发一个动态查询,它允许我在数据库表中定义字段类型,然后提取在创建仪表板期间选择的用户定义字段列表以及为每个字段选择的值。逻辑运算符。
例如,使用可以选择field1
employeeID
。然后,他们可以提供他们想要搜索的ID,并将fieldID
和fieldValue
存储在表中,以便我们在何时需要呈现数据。
现在,根据所选字段的不同,我可能需要加入另一个表格以获取更多信息,例如员工姓名。
虽然这很简单,但是当必须将值加入多个可能的表时,棘手的部分才会发挥作用。如果我存储了employeeID
,我会将该字段与employee表一起加入。但是,如果我存储了storeID
,我需要将该字段与stores表连接起来。
在我走到最后并且意识到我被卡住之前,这是我的想法。基本上,我会说“如果此字段是人员表isPeople=1
,那么加入我们的employeeTable
。
如果此字段isTool=1
,请加入我们的工具表。
我基本上有一个fieldType
和一个fieldValue
,根据类型,我需要加入一个关于我存储的值的特定表。
当我正在努力使它成为动态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 :(得分:0)
您不能动态地连接表,由数据和每行的不同列数驱动。
您只需要使用UNION来组合多个SELECT查询的结果。每个SELECT查询都有不同的连接和WHERE语句(isPeople,isTool等)。
或者您可以加入所有相关表并在ON语句中添加更多条件,如下面的伪代码:
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将为NULL或非NULL,具体取决于fl.isTool和fl.isPeople值。