2016-04-18 32 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)