SELECT * EXCEPT

是否有任何类似SELECT * EXCEPT的RDBMS? 我所追求的是除了特定的TEXT / BLOB字段之外的所有字段,而且我只想select其他所有字段。

几乎每天我都向同事抱怨说有人应该这样做……这是不可能的。

编辑:我了解每个人对SELECT *的关注。 我知道与SELECT *相关的​​风险。 但是,至less在我的情况下,这不会用于任何生产级代码,甚至是开发级代码; 严格的debugging,当我需要很容易地看到所有的值。

正如我在一些评论中所说的,我工作的地方绝对是一个命令行商店,通过ssh进行一切操作。 这使得很难使用任何GUI工具(不允许外部连接到数据库)等等

感谢您的build议,但。

正如其他人所说,在查询中这样做不是一个好主意,因为将来有人在更改表结构时很容易出现问题。 但是,有一种方法可以做到这一点……我不能相信我实际上是在暗示这一点,但本着回答实际问题的精神……

用dynamicSQL做这个…除了“描述”列以外的所有列。 你可以很容易地把它变成一个函数或存储过程。

declare @sql varchar(8000), @table_id int, @col_id int set @sql = 'select ' select @table_id = id from sysobjects where name = 'MY_Table' select @col_id = min(colid) from syscolumns where id = @table_id and name <> 'description' while (@col_id is not null) begin select @sql = @sql + name from syscolumns where id = @table_id and colid = @col_id select @col_id = min(colid) from syscolumns where id = @table_id and colid > @col_id and name <> 'description' if (@col_id is not null) set @sql = @sql + ',' print @sql end set @sql = @sql + ' from MY_table' exec @sql 

在不包含blob列的表上创build一个视图

DB2允许这样做。 列有一个Hidden属性/说明符。

从syscolumns文档


CHAR(1)NOT NULL WITH DEFAULT'N'
指示列是隐式隐藏的:

P部分隐藏。 该列从SELECT *隐式隐藏。

N不隐藏。 该列对所有SQL语句都是可见的。

创build表格文档作为创build列的一部分,您需要指定IMPLICITLY HIDDEN修饰符

下面是隐式隐藏列的示例DDL

 CREATE TABLE T1 (C1 SMALLINT NOT NULL, C2 CHAR(10) IMPLICITLY HIDDEN, C3 TIMESTAMP) IN DB.TS; 

对于未来的读者来说,这种能力是否是推动采用DB2的交易者呢?

远离SELECT *,你正在设置自己的麻烦。 总是准确地指定你想要的列。 事实上,你所要求的“function”并不存在,这实际上相当令人耳目一新。

是否有任何类似SELECT * EXCEPT的RDBMS

是! 真正的关系语言教程D允许投影expression的属性被删除,而不是保留的属性,例如

 my_relvar { ALL BUT description } 

实际上,它相当于SQL的SELECT *{ ALL BUT }

您对SQL的build议是值得的,但是我听说它已经被用户组提交给了SQL标准委员会,并被供应商组织拒绝:(

它也被明确要求SQL Server,但请求被closures为“不会修复”。

我相信它不存在的基本原理是查询的作者(为了performance)只会请求他们将要查看/需要什么(因此知道要指定哪些列) – 如果有人添加了一些在未来的斑点,你会拉回你不需要的潜在的大型领域。

正如其他人所说:SELECT *是一个坏主意。

一些原因:

  1. 只得到你需要的东西(更多的是浪费)
  2. 索引(索引你需要的东西,你可以更快地得到它,如果你也要求一堆非索引的列,你的查询计划将会受到影响。
 declare @sql nvarchar(max) @table char(10) set @sql = 'select ' set @table = 'table_name' SELECT @sql = @sql + '[' + COLUMN_NAME + '],' FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = @table and COLUMN_NAME <> 'omitted_column_name' SET @sql = substring(@sql,1,len(@sql)-1) + ' from ' + @table EXEC (@sql); 

这是一个古老的问题,但我希望这仍然有帮助。

 DECLARE @SQL NVARCHAR(MAX) SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name FROM sys.columns WHERE name <> 'colName' AND object_id = (SELECT id FROM sysobjects WHERE name = 'tblName') SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + 'tblName' EXEC sp_executesql @SQL 

存储过程:

usp_SelectAllExcept'tblname','colname'

 ALTER PROCEDURE [dbo].[usp_SelectAllExcept] ( @tblName SYSNAME ,@exception VARCHAR(500) ) AS DECLARE @SQL NVARCHAR(MAX) SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name from sys.columns where name <> @exception and object_id = (Select id from sysobjects where name = @tblName) SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @tblName EXEC sp_executesql @SQL 

我需要像@Glen要求用HASHBYTES()来缓解我的生活。

我的灵感是@Jasmine和@Zerubbabel的答案。 在我的情况下,我有不同的模式,所以相同的表名不止一次出现在sys.objects。 因为这可能会帮助有相同情况的人,在这里:

 ALTER PROCEDURE [dbo].[_getLineExceptCol] @table SYSNAME, @schema SYSNAME, @LineId int, @exception VARCHAR(500) AS DECLARE @SQL NVARCHAR(MAX) BEGIN SET NOCOUNT ON; SELECT @SQL = COALESCE(@SQL + ', ', ' ' ) + name FROM sys.columns WHERE name <> @exception AND object_id = (SELECT object_id FROM sys.objects WHERE name LIKE @table AND schema_id = (SELECT schema_id FROM sys.schemas WHERE name LIKE @schema)) SELECT @SQL = 'SELECT ' + @SQL + ' FROM ' + @schema + '.' + @table + ' WHERE Id = ' + CAST(@LineId AS nvarchar(50)) EXEC(@SQL) END GO 

临时表选项在这里,只需删除不需要的列,并从修改后的临时表中select*。

 /* Get the data into a temp table */ SELECT * INTO #TempTable FROM table /* Drop the columns that are not needed */ ALTER TABLE #TempTable DROP COLUMN [columnname] SELECT * from #TempTable 

为了完整起见,在DremelSQL方言中可以这样做:

WITH orders AS (SELECT 5 as order_id, "foobar12" as item_name, 800 as quantity) SELECT * EXCEPT (order_id) FROM orders;

+-----------+----------+ | item_name | quantity | +-----------+----------+ | foobar12 | 800 | +-----------+----------+

在没有德雷梅尔的情况下,似乎还有另外一种方法可以做到这一点 。