2016-04-18 33 views
0

我试图显示那些具有值的列,但代码显示每列。 if语句被忽略不知道什么是做错了。 有两张表Person_Permission和Person。我选择Person_Permission中具有值的所有列,在获取那些列名后,我使用这些列从Person表中进行选择。想要仅显示具有值的列

USE [exampleProject] 
GO 
/****** Object: StoredProcedure [dbo].[list_col_notNull] Script Date: 2016/04/18 11:53:51 AM ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[list_col_notNull](@username VARCHAR(20)) 
AS 

    DECLARE @col VARCHAR(255), @cmd VARCHAR(MAX) 

    SELECT * INTO #table FROM Person_Permissions 
    WHERE userName = @username 

    DECLARE getinfo CURSOR FOR 
    SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'Person_Permissions' 

    SET @cmd = 'SELECT ' 

    OPEN getinfo 

    FETCH NEXT FROM getinfo into @col 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 

     IF EXISTS(SELECT TOP 1 * FROM #table WHERE @col IS NOT NULL) 
     BEGIN 
      SET @cmd = @cmd + RTRIM(@col) + ',' 
     END 
     FETCH NEXT FROM getinfo into @col 
    END 

    CLOSE getinfo 
    DEALLOCATE getinfo 
    SET @cmd = LEFT(@cmd, LEN(@cmd) -1) + ' FROM [Person]' 
    select * from #table 
    EXEC(@cmd) 
    SELECT(@cmd) 
+1

什么是最终目标?你不能隐藏显示层中的空列而不是生成动态SQL吗?还是你正在处理一个没有正确数据标准化的糟糕结构? –

+1

您可以添加一些示例数据和预期输出(以及预期/实际生成的查询)吗?你正在从'Person_Permissions'中选择列,并且你最终的查询从'Person'中选择,是否正确? – HoneyBadger

+3

'SELECT TOP 1 * FROM #table WHERE @col IS NOT NULL' - 计算'@ col'变量,它永远不会为null。也许你还需要一些动态查询。但是这会变得臃肿。也许你会更好地隐藏不同应用程序层的列。 – Horia

回答

0

下面是已经做了你通过检查所有值的列长度while语句所以这应该是比光标更高效的寻找什么的例子。

USE [Test] 
GO 

IF EXISTS(SELECT * FROM sys.objects WHERE Name = 'Person_Permissions' AND Type = 'U') 
DROP TABLE [dbo].[Person_Permissions] 
GO 


SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

SET ANSI_PADDING ON 
GO 

--Creating a table to test this out 
CREATE TABLE [dbo].[Person_Permissions](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [FirstName] [varchar](50) NULL, 
    [LastName] [varchar](50) NULL, 
    [UserName] [varchar](50) NULL, 
    [Department] [varchar](50) NULL 
) ON [PRIMARY] 

GO 

SET ANSI_PADDING OFF 
GO 

--Setting some null data 
INSERT INTO [dbo].[Person_Permissions](FirstName,LastName,UserName,Department) 
VALUES('Joe','Smith','JSmith',null) 
GO 


DECLARE @TempColumns TABLE 
(
ID int IDENTITY(1,1), 
ColumnName varchar(100) 
) 

INSERT INTO @TempColumns 
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = 'Person_Permissions' 

DECLARE @Idx int = (select count(*) from @TempColumns)  
DECLARE @ColumnNameSelect varchar(max) = '' 

WHILE @Idx > 0 
BEGIN 

DECLARE @ColumnName varchar(100) = (select ColumnName from @TempColumns where ID = @Idx) 
DECLARE @ValueLength int  
DECLARE @ParmDefinition nvarchar(500) = N'@ValueLengthOUT int OUTPUT'; 
--using a sub query to check length of all values if null make it zero 
DECLARE @Sql nvarchar(max) = ('SELECT @ValueLengthOUT=ISNULL(SUM(A.ValueLength),0) FROM (SELECT LEN([' + @ColumnName + ']) ValueLength FROM [dbo].[Person_Permissions]) AS A') 

exec sp_executesql @Sql, @ParmDefinition, @[email protected] OUTPUT; 

--if there is a value for the column use that column in our select 
IF (@ValueLength > 0) 
BEGIN 
SET @ColumnNameSelect = @ColumnNameSelect + @ColumnName + ',' 
END 

SET @Idx = @Idx - 1 
END 

DECLARE @cmd varchar(max)= 'SELECT ' + (SELECT LEFT(@ColumnNameSelect, LEN(@ColumnNameSelect) -1)) + ' FROM [Person_Permissions]' 

EXEC (@cmd)