2015-10-19 82 views
1

我有一个单独的表格,其中包含问题以及对包含答案的另一个表格和字段的相应引用。喜欢的东西:基于表格内容的SQL JOIN

enter image description here

我想查询的问题表并返回QID,QuestionText和包含在[ResponseTable]值[ResponseField]每个QID。当时的设计灵活多变。然而,应用程序开发人员期待着一个存储过程,而SQL开发人员正指望一个针对此问题的应用程序解决方案。

我在试图建立这个查询的绳索的尽头。你会如何建议完成这项任务?

+0

所以,你是说对响应表的查询会根据问题而有所不同?你有什么参考知道要查找哪个表格?我的第一个想法是应该审查设计。 – InbetweenWeekends

+0

显示的表格是包含近100个问题的主问题表。有20多个潜在的表格位置(ResponseTable)可以显示响应数据,另有20多个潜在字段(ResponseField)。原始设计师认为,通过参考数据的存放位置和动态显示问答数据来管理一组问题会更容易。 – Quark

+0

您可能必须使用动态SQL来完成此操作,但它有一些主要的安全隐患。 https://msdn.microsoft.com/en-us/library/ms188001.aspx – Dijkgraaf

回答

0

我不认为你会喜欢听到这个答案,因为它可能意味着一些重大的返工,但我认为这是正确的答案。摆脱问题表并将问题放入Client1,Client9和Jobs表中新的问题字段中;每个响应一个。

例如,客户端1表有以下字段:

ColorPref 
ColorPrefQuestion 
Rating 
RatingQuestion 

...等等

周围的设计工作围绕你现在将是一个头疼的设计工作会在哪里管理。

+0

不幸的是,我不认为这是可能的。对于给定的客户表,可能存在无限的问题变化,因为多个客户使用相同的基础表。我同意,如果此应用程序是从头开始创建的,则您的方法将是理想的。我只是继承了这份工作的混乱,并且努力保持它的功能性,直到下一次重大改写。 – Quark

0

这听起来像应该考虑重新设计(例如,将所有响应存储在一张表中),但如果这不可行,则可以使用dynamic SQL (using sp_executesql)。但是,由于容易受到SQL injection的影响,因此使用可能会很危险。可以采取一些预防措施,例如在表名和列名上使用QUOTENAME。在使用动态SQL之前,这也是一个很好的阅读:The Curse and Blessings of Dynamic SQL

DECLARE @tableName NVARCHAR(50) 
DECLARE @columnName NVARCHAR(50) 
DECLARE @query NVARCHAR(MAX) 

SET @tableName = 'Client1' 
SET @columnName = 'ColorPref' 
SET @query = 'SELECT ' + QUOTENAME(@columnName) + ' FROM ' + QUOTENAME(@tableName) 

EXEC sp_executesql @query 
+0

感谢您的回应,我已经考虑过动态SQL路线,甚至在今天早些时候查看了参考文章。这段代码是否仍然需要知道columnName和tableName。我认为这种方法背后的理论最初是基于主表获取给定问题集的所有问题和答案。我很乐意进行重新设计,但考虑到答案的分散性,我不知道另一个好的选择。数据的生命如此根深蒂固,以至于这部分可能永远不会改变。 – Quark

+0

SQL注入可能不是问题,因为查询不使用任何外部提供的输入,只是已经在表中的数据。 – TMN

+0

@Quark不,数据不需要预先知道。这只是一个例子。 '@ tableName'和'@ columnName'的值可以来自任何地方。在你的情况下,我假设你会从基于QID的问题表中选择它们。 –

0

直到重新提到您提到的时候,请考虑使用视图将这些响应表放在一起的想法。

CREATE VIEW ClientResponses AS 
    SELECT QID, ResponseField FROM [Client1] 
    UNION 
    SELECT QID, ResponseField FROM [Jobs] 
    UNION 
    SELECT QID, ResponseField FROM [Client9] 
    -- ..... add the new tables as they are created 

这将

  1. 避免动态SQL
  2. 给你一个地方来维持查询
  3. 提供一个非常简单的,可读的方式蹒跚了一起