我遵循了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”附近的语法不正确。“
答案 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)