根据用户输入检索/显示列

时间:2018-07-22 11:45:36

标签: tsql select ssms

我有两个桌子。

MainTable

MainTable

FIELDS_ACTIVATION

Fields

我将在ASP.NET中构建一个页面,用户可以从该页面查看MainSampleTable中的所有记录。

但是,(由于GDPR)我必须构建一个存储过程,该过程使用户能够从此页面(可能从下拉列表)中选择类别。当用户选择类别1时,我将需要使类别ID与用户选择的内容匹配的IsActive列字段变为1。因此,如果用户选择1,则类别ID = 1,则IsActive应= 1(true)(字段激活表)。

发生这种情况时,我需要从主样本表中选择/显示与IsActive中值为1的字段激活表中的字段名称匹配的列。

到目前为止,这是我的代码。

DECLARE @category INT = 1

                --Set Default Values (All disabled (false) until user selects a category)
                UPDATE Company.FileExtraction.FIELDS_ACTIVATION
                SET IsActive = 0

                --If Category is 1, Set IsActive to 1, Where CategoryId is 1 in FIELDS_ACTIVATION table
                IF OBJECT_ID('tempdb..#CatOneTemp') IS NOT NULL DROP TABLE #CatOneTemp
                IF @category = 1
                    BEGIN
                        UPDATE Company.FileExtraction.FIELDS_ACTIVATION
                        SET IsActive = 1
                        WHERE CategoryID = 1

                        --Select appropriate fields and put into temp table
                        SELECT REPLICATE('0', 10-LEN(EM.ColumnA)) + EM.ColumnA AS PolicyNumber,
                               REPLICATE('0', 7-LEN(ColumnB)) + ColumnB AS BOCBranch,
                               ColumnC + REPLICATE(' ', 10-LEN(ColumnC)) AS ContributionCode
                        INTO #CatOneTemp
                        FROM Company.FileExtraction.MainTable EM

                        SELECT * FROM #CatOneTemp
                    END

我不能加入表格,因为我没有共同的理由。我已经尝试过使用子查询,但是我无法理解如何构成这种查询。

我不禁想到有一个更好的方法,但是这种方法已经由其他人提供给我实施,我不能反对。就个人而言,我希望当用户选择一个时,选择columnA和columnB,当选择2时,选择columnC和columnD,而不使用IsActive列。但是嘿指令就是指令。显然是有原因的。

编辑

我已经更新了代码。 我希望当前代码仅在字段激活表中的SELECT列为1且仅对与该列匹配的IsActive进行FieldNames MainSampleTable中的名称。

基本上,我需要IsActive = 1作为SELECT语句的强制条件。

我也在Select records in on table based on conditions from another table?处进行了检查,但这要求两个表具有一个公共字段。 (例如type_id)。那篇文章中的想法就是我的追求。

希望是有意义的,如果有任何不合理的地方,我们很乐意澄清。

2 个答案:

答案 0 :(得分:0)

这不是很漂亮,但至少会得到您想要的答案:

SELECT *
INTO #MainSampleTable
FROM (SELECT 'John' AS ColumnA, 'Doe' AS ColumnB, 'Clark St.' AS ColumnC, 'Telford' AS ColumnD, 'UK' AS ColumnE, '2300' AS ColumnF UNION ALL
SELECT 'Jane' AS ColumnA, 'Doe' AS ColumnB, 'Lister gdns.' AS ColumnC, 'London' AS ColumnD, 'UK' AS ColumnE, '2300' AS ColumnF UNION ALL
SELECT 'John' AS ColumnA, 'Smith' AS ColumnB, 'Clurk St.' AS ColumnC, 'Bradford' AS ColumnD, 'UK' AS ColumnE, '2300' AS ColumnF UNION ALL
SELECT 'John' AS ColumnA, 'Jones' AS ColumnB, 'Clork St.' AS ColumnC, 'Tellane' AS ColumnD, 'UK' AS ColumnE, '2325' AS ColumnF UNION ALL
SELECT 'John' AS ColumnA, 'Long' AS ColumnB, 'Clyrk St.' AS ColumnC, 'Ford' AS ColumnD, 'UK' AS ColumnE, '2350' AS ColumnF
) AS Names;


SELECT *
INTO #FieldActivationSample
FROM (SELECT '1' AS CategoryId, 'ColumnA' AS FieldName, 0 AS IsActive UNION ALL
SELECT '1' AS CategoryId, 'ColumnB' AS FieldName, 0 AS IsActive UNION ALL
SELECT '2' AS CategoryId, 'ColumnC' AS FieldName, 0 AS IsActive UNION ALL
SELECT '2' AS CategoryId, 'ColumnD' AS FieldName, 0 AS IsActive UNION ALL
SELECT '3' AS CategoryId, 'ColumnE' AS FieldName, 0 AS IsActive UNION ALL
SELECT '3' AS CategoryId, 'ColumnF' AS FieldName, 0 AS IsActive 
) AS Fields;



    --User input parameter
DECLARE @categoryId VARCHAR(1) = '1'

--If User selects 1 set IsActive to 1 Where Field Name = 'ColumnA' and 'ColumnB'
IF @categoryId = '1'
UPDATE #FieldActivationSample
SET IsActive = 1
WHERE FieldName IN ('ColumnA', 'ColumnB');


--This is where I am stuck

--Select the columns from MainSampleTable, 
--which have names that match values in the FieldName column,
--that have an IsActive status of 1, 
--from the FieldActivationTable
DECLARE @FieldList varchar(1000);
DECLARE @DynamicFields nvarchar(4000);
SELECT @FieldList = Stuff((Select ',' +replace(FieldName,'z','')
FROM (SELECT FieldName 
        FROM #FieldActivationSample
        WHERE IsActive = 1                      
      ) C1
FOR XML PATH ('')),1,1,'');

SET @DynamicFields = 'SELECT ' + @FieldList + ' FROM #MainSampleTable';

EXECUTE sp_executesql @DynamicFields;


DROP TABLE #MainSampleTable;
DROP TABLE #FieldActivationSample;

答案 1 :(得分:0)

我有一个简化的解决方案。我认为您需要使用FieldActivationSample表来缝合查询列的功能。为此,您将需要创建一个动态查询。使用Quotename的动态查询列,并带有逗号,您必须先删除逗号然后再运行它。 让我知道它是否有效。

CREATE TABLE MainSampleTable (ColumnA varchar(20), ColumnB varchar(20),  ColumnC varchar(20), ColumnD varchar(20), ColumnE varchar(20),  ColumnF varchar(20))
INSERT INTO MainSampleTable
SELECT 'John', 'Doe', 'Clark St.', 'Telford', 'UK', '2300' UNION ALL
SELECT 'Jane', 'Doe', 'Lister gdns.', 'London', 'UK', '2300' UNION ALL
SELECT 'John', 'Smith', 'Clurk St.', 'Bradford', 'UK', '2300' UNION ALL
SELECT 'John', 'Jones', 'Clork St.', 'Tellane', 'UK', '2325' UNION ALL
SELECT 'John', 'Long', 'Clyrk St.', 'Ford', 'UK', '2350'

CREATE TABLE FieldActivationSample (CategoryId INT, FieldName varchar(50), IsActive BIT)
INSERT INTO FieldActivationSample
SELECT '1', 'ColumnA', 1 UNION ALL
SELECT '1', 'ColumnB', 1 UNION ALL
SELECT '2', 'ColumnC', 0 UNION ALL
SELECT '2', 'ColumnD', 0 UNION ALL
SELECT '3', 'ColumnE', 0 UNION ALL
SELECT '3', 'ColumnF', 0 



--Ability to use a table to stitch columns using dynamic query --
DECLARE @ColumnList nvarchar(1000)=(SELECT Quotename(FieldName) + ',' FROM FieldActivationSample WHERE IsActive=1 FOR xml path(''))--- @Column List
SELECT @ColumnList = LEFT(@ColumnList, Len(@ColumnList) - 1)  --- Remove comma
--Generate Query ----
DECLARE @Dynamicsql nvarchar(1000)   = 'SELECT ' + @ColumnList + ' FROM MainSampleTable '
--Test Query  ---
PRINT (@Dynamicsql) 
--To run--
EXEC(@DynamicFields)