如何选择除SQL中指定列之外的所有列

时间:2018-02-14 16:11:27

标签: sql sql-server database sql-server-2012 ssms

我遵循了Anthony Faull提供的逻辑 SQL exclude a column using SELECT * [except columnA] FROM tableA?

这是我写的代码

if OBJECT_ID('tempdb..#ReportRows') is not null
drop table #ReportRows

Select * 
into #ReportRows
from
(Select 
Alpha,Beta,Gamma,XMan,Pathwaycode,STDCode,JiraCode
from 'Table1'
)
order by alpha

DECLARE @columns varchar(8000)

SELECT @columns = ISNULL(@columns + ', ','') + QUOTENAME(column_name)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '#ReportRows' AND COLUMN_NAME not in ('[PathwayCode]','[Gamma]')
ORDER BY ORDINAL_POSITION

EXEC ('SELECT ' + @columns + 'FROM #ReportRows')

每次我运行此操作时都会出现以下错误 “Msg 156,Level 15,State 1,Line 3 关键字“FROM”附近的语法不正确。“

2 个答案:

答案 0 :(得分:1)

如果必须使用动态SQL执行此操作,这应该可以帮助您入门:

DECLARE @SQL nvarchar(MAX);

SELECT @SQL = N'SELECT ' +
              STUFF(CONVERT(varchar(MAX),(SELECT N',' + NCHAR(10) + QUOTENAME(c.[name])
                                          FROM sys.columns c
                                               JOIN sys.tables t ON c.object_id = t.object_id
                                          WHERE c.[name] NOT IN (N'PathwayCode',N'Gamma')
                                          --Note I use STRING_SPLIT ehre, which is a 2016 Function
                                          --You'll need to find a String Splitter for prior versions
                                            AND t.[name] = N'YourTable'
                                          FOR XML PATH(N''), TYPE)),1,2,N'') + NCHAR(10) +
              N'FROM YourTable;';

PRINT @SQL;
EXEC sp_executesql @SQL;

老实说,这似乎比解决的工作更多;特别是因为我们只省略了2列。 SSMS可以轻松地为所有列提供SELECT语句,然后您可以轻松地从语句中删除它们。

如果您需要更永久的对象,请使用VIEW

编辑:

如果你想真正做到这一点"真的"动态,你可以这样做:

CREATE PROC Select_Exclude @Table sysname, @Columns nvarchar(4000) AS

    DECLARE @SQL nvarchar(max);

    SELECT @SQL = N'SELECT ' +
                  STUFF(CONVERT(varchar(MAX),(SELECT N',' + NCHAR(10) + QUOTENAME(c.[name])
                                              FROM sys.columns c
                                                   JOIN sys.tables t ON c.object_id = t.object_id                                               
                                              WHERE c.[name] NOT IN (SELECT SS.[value] FROM STRING_SPLIT(@Columns,',') SS)
                                                AND t.[name] = N'YourTable'
                                              FOR XML PATH(N''), TYPE)),1,2,N'') + NCHAR(10) +
                  N'FROM ' + QUOTENAME(ot.[name]) + ';'
    FROM sys.tables ot
    WHERE ot.[name] = @Table;

    PRINT @SQL;
    EXEC sp_executesql @SQL;
GO

EXEC Select_Exclude @Table = N'YourTable', @Columns = N'PathwayCode,Gamma';

但是,为什么......?这只是顶部。我真的这样做是为了证明这一点。

答案 1 :(得分:0)

我已经使用了您的代码并为您创建了一个带有测试输出的示例。请试试。

生成数据。

USE [master]
GO
/****** Object:  Table [dbo].[FindRecordsWithALength]    Script Date: 2/14/2018 10:01:49 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[FindRecordsWithALength](
    [Id] [int] NULL,
    [Name] [varchar](10) NULL,
    [Length] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[FindRecordsWithALength] ([Id], [Name], [Length]) VALUES (1, N'A', 5)
GO
INSERT [dbo].[FindRecordsWithALength] ([Id], [Name], [Length]) VALUES (2, N'B', 3)
GO
INSERT [dbo].[FindRecordsWithALength] ([Id], [Name], [Length]) VALUES (3, N'C', 4)
GO
INSERT [dbo].[FindRecordsWithALength] ([Id], [Name], [Length]) VALUES (4, N'D', 5)
GO

解决方案

IF OBJECT_ID('tempdb..#ReportRows') IS NOT NULL
DROP TABLE #ReportRows

SELECT * INTO #ReportRows from FindRecordsWithALength

DECLARE @columns VARCHAR(MAX) = ''
DECLARE @SQL VARCHAR(MAX) = ''

SELECT @columns = ISNULL(@columns + ',','') + QUOTENAME(a.NAME) 
FROM tempdb.sys.columns a 
INNER JOIN tempdb.sys.objects s ON a.object_id = s.object_id
WHERE s.NAME like  '#ReportRows%' AND s.Type = 'U'
AND a.NAME NOT IN  ('Name')

SET @SQL = 'SELECT ' + SUBSTRING(@columns,2,LEN(@columns))  + ' FROM #ReportRows '

EXEC(@SQL)

<强>输出

 Id          Length
    ----------- -----------
    1           5
    2           3
    3           4
    4           5

    (4 rows affected)