Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择*除_Sql_Sql Except - Fatal编程技术网

Sql 选择*除

Sql 选择*除,sql,sql-except,Sql,Sql Except,是否有任何RDBMS实现类似SELECT*的功能?我要做的是获取除特定文本/BLOB字段之外的所有字段,我只想选择其他所有字段 我几乎每天都向我的同事抱怨应该有人来实施这个。。。它根本不存在,真让人讨厌 编辑:我理解每个人对SELECT*的关注。我知道与SELECT*相关的风险。然而,至少在我的情况下,这不会用于任何生产级代码,甚至开发级代码;严格用于调试,当我需要轻松查看所有值时 正如我在一些评论中所说的,我工作的地方严格来说是一个命令行商店,通过ssh做所有事情。这使得使用任何gui工具变得

是否有任何RDBMS实现类似SELECT*的功能?我要做的是获取除特定文本/BLOB字段之外的所有字段,我只想选择其他所有字段

我几乎每天都向我的同事抱怨应该有人来实施这个。。。它根本不存在,真让人讨厌

编辑:我理解每个人对SELECT*的关注。我知道与SELECT*相关的风险。然而,至少在我的情况下,这不会用于任何生产级代码,甚至开发级代码;严格用于调试,当我需要轻松查看所有值时

正如我在一些评论中所说的,我工作的地方严格来说是一个命令行商店,通过ssh做所有事情。这使得使用任何gui工具变得困难,不允许外部连接到数据库,等等


不过,谢谢你的建议。

远离SELECT*,你正在给自己找麻烦。始终精确指定所需的列。事实上,令人耳目一新的是,您所要求的功能不存在。

我认为不存在该功能的理由是,为了性能起见,查询的作者应该只请求他们将要查看/需要的内容,因此知道要指定的列-如果将来有人添加了几个blob,您将收回可能不需要的较大字段。

正如其他人所说:选择*是个坏主意

一些原因:

只得到你需要的东西,再多的东西都是浪费 索引你所需要的,你可以得到它更快。如果您还需要一堆未编制索引的列,那么您的查询计划将受到影响。
在表上创建一个不包含blob列的视图

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

用动态SQL做它。。。这将执行除“说明”列之外的所有列。您可以轻松地将其转换为函数或存储过程

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
是否有任何RDBMS实现类似SELECT*的功能

对!!真正的关系语言允许根据要删除的属性而不是要保留的属性来表达投影,例如

my_relvar { ALL BUT description }
事实上,它相当于SQL的SELECT*是{ALL BUT}

您的SQL提案很有价值,但我听说它已经被用户组提交给SQL标准委员会,并被供应商组拒绝:


它也被关闭了,但请求被关闭为“不会修复”。

DB2允许这样做。列具有隐藏的属性/说明符

隐藏的 CHAR1不为NULL,默认为“N” 指示列是否隐式隐藏:

p部分隐藏。该列对SELECT*隐式隐藏

没有隐藏。该列对所有SQL语句都可见

作为创建列的一部分,您可以指定隐式隐藏修饰符

下面是一个DDL示例


这项功能是否能够推动DB2的采用,留给未来的读者做一个练习。

这是一个老问题,但我希望这个答案仍能对其他人有所帮助。也可以对其进行修改以添加。如果您想使用多个列,这将非常方便

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来缓解我的生活

我的灵感来自《茉莉花和所罗巴伯的答案》。在我的例子中,我有不同的模式,因此同一个表名在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

临时表选项,只需删除不需要的列,然后从修改后的临时表中选择*即可

/* 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方言中是可能的,可以执行以下操作:

以命令作为 选择5作为订单id, foobar12作为项目名称, 800作为数量 选择*除订单id外 从命令

+------+-----+ |项目名称|数量| +------+-----+ |foobar12 | 800| +------+-----+


似乎还有另一种方法可以不用Dremel来实现这一点。

是的,最后是:SQL标准2016定义

SQL:2016引入了无需预先指定结果类型的多态表函数。相反,它们可以提供一个描述组件过程,用于确定运行时的返回类型。PTF的作者和用户都不需要事先声明返回的列

SQL:2016描述的PTF尚未在任何测试数据库中提供。10感兴趣的读者可参考ISO发布的免费技术报告“SQL中的多态表函数”。以下是一些 报告中讨论的例子如下:

CSVreader,它读取CVS文件的头行以确定返回列的数量和名称

Pivot实际上是unpivot,它将列组转换为行示例:phonetype、phonenumber-me:不再使用harcoded字符串:

topnlus,它在每个分区中通过N行,在剩余行的总数中再通过一行

oracle18c实现了这种机制。及

此示例显示如何基于名称/特定数据类型跳过数据:

CREATE PACKAGE skip_col_pkg AS  
  -- OVERLOAD 1: Skip by name 
  FUNCTION skip_col(tab TABLE,  col columns)  
           RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;  
  
  FUNCTION describe(tab IN OUT dbms_tf.table_t,   
                    col        dbms_tf.columns_t)  
           RETURN dbms_tf.describe_t;  
  
  -- OVERLOAD 2: Skip by type --  
  FUNCTION skip_col(tab       TABLE,   
                    type_name VARCHAR2,  
                    flip      VARCHAR2 DEFAULT 'False')   
           RETURN TABLE PIPELINED ROW POLYMORPHIC USING skip_col_pkg;  
  
  FUNCTION describe(tab       IN OUT dbms_tf.table_t,   
                    type_name        VARCHAR2,   
                    flip             VARCHAR2 DEFAULT 'False')   
           RETURN dbms_tf.describe_t;  
END skip_col_pkg;
和机构:

CREATE PACKAGE BODY skip_col_pkg AS  
  
/* OVERLOAD 1: Skip by name   
 * NAME:  skip_col_pkg.skip_col   
 * ALIAS: skip_col_by_name  
 *  
 * PARAMETERS:  
 * tab - The input table  
 * col - The name of the columns to drop from the output  
 *  
 * DESCRIPTION:  
 *   This PTF removes all the input columns listed in col from the output  
 *   of the PTF.  
*/   
  FUNCTION  describe(tab IN OUT dbms_tf.table_t,   
                     col        dbms_tf.columns_t)  
            RETURN dbms_tf.describe_t  
  AS   
    new_cols dbms_tf.columns_new_t;  
    col_id   PLS_INTEGER := 1;  
  BEGIN   
    FOR i IN 1 .. tab.column.count() LOOP  
      FOR j IN 1 .. col.count() LOOP  
      tab.column(i).pass_through := tab.column(i).description.name != col(j);  
        EXIT WHEN NOT tab.column(i).pass_through;  
      END LOOP;  
    END LOOP;  
  
    RETURN NULL;  
  END;  
    
 /* OVERLOAD 2: Skip by type  
 * NAME:  skip_col_pkg.skip_col   
 * ALIAS: skip_col_by_type  
 *  
 * PARAMETERS:  
 *   tab       - Input table  
 *   type_name - A string representing the type of columns to skip  
 *   flip      - 'False' [default] => Match columns with given type_name  
 *               otherwise         => Ignore columns with given type_name  
 *  
 * DESCRIPTION:  
 *   This PTF removes the given type of columns from the given table.   
*/   
  
  FUNCTION describe(tab       IN OUT dbms_tf.table_t,   
                    type_name        VARCHAR2,   
                    flip             VARCHAR2 DEFAULT 'False')   
           RETURN dbms_tf.describe_t   
  AS   
    typ CONSTANT VARCHAR2(1024) := upper(trim(type_name));  
  BEGIN   
    FOR i IN 1 .. tab.column.count() LOOP  
       tab.column(i).pass_through :=   
         CASE upper(substr(flip,1,1))  
           WHEN 'F' THEN dbms_tf.column_type_name(tab.column(i).description)
     !=typ  
           ELSE          dbms_tf.column_type_name(tab.column(i).description) 
     =typ  
         END /* case */;  
    END LOOP;  
  
    RETURN NULL;  
  END;  
  
END skip_col_pkg;  
和示例用法:

-- skip number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number'); 

-- only number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number', flip => 'True') 

-- skip defined columns
SELECT *   
FROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr))  
WHERE deptno = 20;
我强烈建议阅读整个示例创建独立函数,而不是包调用

您可以轻松重载skip方法,例如:跳过不以特定前缀/后缀开头/结尾的列

相关的:

是否有任何RDBMS实现类似SELECT*的功能

是的,Google Big Query实现了:

SELECT*EXCEPT语句指定要从结果中排除的一个或多个列的名称。输出中将忽略所有匹配的列名

输出:

+-----------+----------+
| item_name | quantity |
+-----------+----------+
| sprocket  | 200      |
+-----------+----------+
编辑:

H2数据库还支持SELECT*除col1、col2、。。。语法

SELECT语句中的通配符表达式。通配符表达式表示所有可见列。可以使用可选EXCEPT子句排除某些列

编辑2:

配置单元支持:

如果配置属性Hive.support.quoted.identifiers设置为none,则SELECT语句可以在0.13.0之前的配置单元版本中,或在0.13.0及更高版本中采用基于正则表达式的列规范

以下查询选择除ds和hr之外的所有列



幸运的是,我们的桌子几乎从不改变。我专门为调试问题考虑这个问题,我需要所有其他字段,除了BLOB。在那个特定的情况下,我同意拥有它会很好。这里的操作词几乎是。此外,任何好的sql工具都允许您单击并选择所需的内容,而不会用这种装置污染语言。@gms8994,在调试过程中,大多数企业RDBMS将自动为您编写select语句的脚本,其中包括所有列。然后删除你的“恶心”专栏,你就可以开始了。这并不能回答问题。有时,此功能将非常有用,即使可能受到与*相同的滥用。具体地说,我想做这样的事情的时候是在带有标识列的表中克隆行时。然后它将是方便的,能够做插入。。。全选,但id…+1:这很合理-此处也不允许选择*。如果源表发生更改,则需要修改视图。如果你要在上面使用SELECT*的话,不妨选择你真正想开始的列,这样你就不用反复输入那些列了。对于开发人员来说,在调试中使用它不是一个坏主意。我已经在我的新电脑上进行了剪切和粘贴-如果你总是想保留select语句和其他类似语句,那就太好了。我的桌面上有足够多的杂物。打开一个文件、复制和粘贴比做一个简单的选择还需要更多的工作,本着回答实际问题的精神,你赢得了奖品。我可以想到几个原因,为什么你可能需要这样做,而不是发疯。另外,这是一个有趣的问题,不管是什么问题,弄清楚这一点都很有趣:首先,感谢你回答这个问题,而不是就这个人是否应该做这件事发表意见。执行此操作的一个主要方案是创建一个视图,如果基础表列发生更改,您希望该视图能够拾取这些列,并将在拾取特定列的其他select语句中使用。exec@sql获取名称“在此处插入680个sql语句变量字符中的644”不是有效标识符。应该是执行董事@sql@Rebeccah-通常这意味着您的语句中有语法错误。通常是不平衡的引号。动态sql很容易出现这种情况,很容易与任何地方的所有quotey标记混淆。EXCEPT关键字确实存在于sql Server中,尽管它不打算按您希望的方式在问题中使用。它在两个结果集之间执行差异并集,以向您提供第一个结果集中存在但第二个结果集中不存在的记录的结果集。请确认该结果集不存在。@VISQL的可能重复项现在就可以了exists@VISQL请核对我的答案我不同意你的观点,因为获取列首先与索引和执行计划无关。如果要按列联接表,或者要在符合条件的时间内限制列上的数据,可以向列添加索引。当您通过连接选择五个表时,选择一列或200列实际上并不重要,这只是获取数据的问题。@bobbel我必须坚持这一点
如果索引包含所请求的列,那么除了查找所需的记录外,它还可以绝对改进检索。覆盖索引可以通过从索引本身回答整个查询/连接等来产生巨大的性能改进,而无需访问生成索引的底层数据。有用的信息,但不能真正回答问题。我现在住在t-SQL世界。关于BigQuery,有些事情我真的很怀念!这是他们的传统方言还是标准方言?@Dodecaphone这是BigQuery的标准方言
-- skip number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number'); 

-- only number cols
SELECT * FROM skip_col_pkg.skip_col(scott.dept, 'number', flip => 'True') 

-- skip defined columns
SELECT *   
FROM skip_col_pkg.skip_col(scott.emp, columns(comm, hiredate, mgr))  
WHERE deptno = 20;
WITH orders AS(
  SELECT 5 as order_id,
  "sprocket" as item_name,
  200 as quantity
)
SELECT * EXCEPT (order_id)
FROM orders;
+-----------+----------+
| item_name | quantity |
+-----------+----------+
| sprocket  | 200      |
+-----------+----------+
SELECT `(ds|hr)?+.+` FROM sales