我正在研究动态查询,该查询允许我在数据库表中定义字段类型,然后提取在创建仪表板时选择的用户定义字段的列表以及为每个逻辑选择的值运营商。TSQL有条件加入声明?
例如,使用可以选择field1
这就是employeeID
。然后他们可以提供他们想要搜索的ID,并且它将在我们需要呈现数据时将fieldID
和fieldValue
存储在表中。
现在取决于所选择的字段,我可能需要加入另一个表以获取更多信息,例如员工姓名。
虽然这很简单,但棘手的部分发挥作用时,必须加入对多个可能的表的值。如果我存储employeeID
,我会将该字段与雇员表一起加入。但是,如果我存储了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
发布您的代码 – Amit
我认为您可能会从使用ORM工具获益,因此您可以在代码层中进行更多动态查询,或者可以使用多个查询并在几次旅行中提取数据数据库而不是试图一次性完成这一切....我一直在走你要走的道路,做动态动态查询并不是一条好路径。如果你的数据集有点大,你很快就会遇到性能问题。 –
你是否也可以提供所有的字段给用户,并保留空白('NULL')并检查连接条件?这样,您可以始终加入所有表格,但仅限于使用的参数。 – NickyvV