2009-01-05 28 views
41

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

幾乎每天我抱怨我的同事,有人要實現這個...這是非常惱人的,它不存在。

編輯:我瞭解大家對SELECT *的關注。我知道與SELECT *相關的風險。但是,至少在我的情況下,這不會用於任何生產級別的代碼,甚至不用於開發級別的代碼;嚴格要求調試,當我需要很容易地看到所有的值。

正如我在一些評論,我在那裏工作的已經說是嚴格意義上的命令行店,千方百計通過ssh。這使得它很難使用任何GUI工具(外部連接到數據庫中是不允許的),等等等等

感謝您的建議,但。

+0

在SQL Server中,EXCEPT關鍵字確實存在,但它並不打算在您的問題中使用。它在兩個結果集之間執行DIFFERENCE UNION,以給出第一個結果集中存在但不存在於第二個結果集中的「記錄」的結果集。 – 2009-02-02 17:42:36

+3

它吮吸它不存在。 – VISQL 2012-06-29 23:51:35

+1

可能重複的[SQL使用SELECT \ * \ [列columnA \] FROM tableA除外列](http://stackoverflow.com/questions/729197/sql-exclude-a-column-using-select-except- columna-from-tablea) – billinkc 2015-03-31 21:01:38

回答

25

,它是不是一個好主意在查詢中執行此操作,因爲將來有人在更改表結構時很容易出現問題。然而,有一種方法可以做到這一點......我不能相信我居然暗示這一點,但在回答實際問題的精神......

使用動態SQL做...這個除了「description」列以外的所有列。你可以很容易地把它變成一個函數或存儲過程。

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 
5

遠離從SELECT *,你是在和自己的麻煩。 總是指定你想要的列。事實上,您所要求的「功能」並不存在,這相當令人耳目一新。

2

我認爲它不存在的理由是,查詢的作者應(爲了性能考慮)只要求他們會怎麼看/需求(並因此知道指定哪些列) - 如果有人將來會增加更多的斑點,你會拉回你不需要的潛在大型領域。

1

正如其他人都在說:SELECT *是一個壞主意。

一些原因:

  1. 僅獲得你所需要的(東西更是一種浪費)
  2. 索引(索引你需要什麼,你可以更迅速地得到它,如果你問了一堆非。 -indexed列,同樣,你的查詢計劃將受到影響。
23

在表上創建一個視圖不包括正如其他人所說的BLOB列

0
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); 
5

有沒有實現類似SELECT *除

是任何RDBMS!真正的關係語言Tutorial D允許投影根據要去除的屬性而不是要保留的屬性來表示,

my_relvar { ALL BUT description } 

事實上,它相當於SQL的SELECT *{ ALL BUT }

您的SQL的建議是值得一個,但我聽說它已經被放置到被用戶組SQL標準的委員會,並拒絕了供應商的組:(

它也一直explicitly requested for SQL Server但請求被關閉爲 '不會修復'。

9

DB2允許此。的列具有的Hidden屬性/符。

syscolumns documentation

HIDDEN
CHAR(1)WITH DEFAULT NOT NULL 'N'
指示列是否被隱式隱藏:

P部分隱藏。該列對SELECT *隱式隱藏。

N未隱藏。該列對所有SQL語句都可見。

Create table documentation作爲創建柱的一部分,你會指定IMPLICITLY HIDDEN修改

Implicitly Hidden Columns一個例子DDL如下

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

無論這種能力是這樣的交易商來驅動採納DB2作爲未來讀者的練習。

0

這是一個古老的問題,但我希望這仍然有幫助。

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 
0

我需要的東西像什麼@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 
0

臨時表在這裏的選擇,只是降不需要列,從改變後的臨時表中選擇*。

/* 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 
0

爲了完整起見,這是可能的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 | +-----------+----------+

看起來也似乎是另一種方式來做到這一點here無的Dremel。

1

是,終於有:) SQL標準2016定義Polymorphic Table Functions

SQL 2016引入了不需要指定結果類型前期多態表函數(PTF)。相反,他們可以提供一個在運行時確定返回類型的描述組件過程。 PTF的作者和PTF的用戶都不需要提前申報退回的專欄。

SQL:2016描述的PTF在任何測試的數據庫中都不可用。有興趣的讀者可參考ISO發佈的免費技術報告「SQL中的多態表函數」。以下是一些的報告中所討論的實施例中:

  • CSVreader,其內容CVS文件的標題行來確定返回的列數和名稱

  • 樞軸(實際上逆透視) ,果然列組成列(例如:PHONETYPE,PHONENUMBER) - 我:沒有更多harcoded串:)

  • TopNplus,其穿過每個分區和一個額外的行N行與剩餘行

    的總計

Oracle 18c實現這一機制。 18c Skip_col Polymorphic Table Function Example Oracle Live SQLSkip_col Polymorphic Table Function Example

這個例子說明了如何基於名稱/特定數據類型跳過數據:

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方法,例如:跳過不以特定前綴/後綴開始/結束的列。