61

のようなものを実装する RDBMS はありますSELECT * EXCEPTか? 私が求めているのは、特定の TEXT/BLOB フィールドを除くすべてのフィールドを取得することです。それ以外はすべて選択したいと思います。

ほぼ毎日、誰かがこれを実装するべきだと同僚に不平を言っています... それが存在しないのはひどく迷惑です。

編集:に対する皆さんの懸念を理解していSELECT *ます。に伴うリスクを知っていますSELECT *。ただし、これは、少なくとも私の状況では、製品レベルのコードや開発レベルのコードには使用されません。すべての値を簡単に確認する必要がある場合は、厳密にデバッグ用です。

いくつかのコメントで述べたように、私が働いている場所は厳密にはコマンドライン ショップであり、すべてを ssh で実行しています。これにより、GUI ツールの使用が困難になります (データベースへの外部接続は許可されません) など。

しかし、提案をありがとう。

4

14 に答える 14

38

他の人が言ったように、誰かが将来テーブル構造を変更したときに問題が発生する可能性があるため、クエリでこれを行うことはお勧めできません。ただし、これを行う方法はあります...実際にこれを提案しているとは信じられませんが、実際の質問に答えるという精神で...

動的 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
于 2009-01-05T17:39:08.663 に答える
25

BLOB 列を含まないテーブルにビューを作成する

于 2009-01-05T17:22:16.500 に答える
12

SELECT * EXCEPT のようなものを実装する RDBMS はありますか?

はい、Google Big Query はSELECT * EXCEPTを実装しています:

SELECT * EXCEPT ステートメントは、結果から除外する 1 つ以上の列の名前を指定します。一致する列名はすべて出力から省略されます。

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      |
+-----------+----------+

編集:

H2 データベースはSELECT * EXCEPT (col1, col2, ...)構文もサポートしています。

ワイルドカード式

SELECT ステートメントのワイルドカード式。ワイルドカード式は、表示されるすべての列を表します。一部の列は、オプションの EXCEPT 句で除外できます。


編集2:

Hive のサポート: REGEX 列の仕様

SELECT ステートメントは、構成プロパティ hive.support.quoted.identifiers が none に設定されている場合、0.13.0 より前の Hive リリース、または 0.13.0 以降のリリースで正規表現ベースの列指定を取ることができます。

次のクエリは、ds と hr を除くすべての列を選択します。

SELECT `(ds|hr)?+.+` FROM sales
于 2018-04-10T17:52:44.943 に答える
5

SELECT * EXCEPT のようなものを実装する RDBMS はありますか

はい!真のリレーショナル言語のチュートリアル Dでは、保持する属性ではなく、削除する属性の観点からプロジェクションを表現できます。

my_relvar { ALL BUT description }

実際、SQL に相当するのSELECT *{ ALL BUT }.

SQL に対するあなたの提案は価値のあるものですが、ユーザー グループによって SQL 標準委員会に提出され、ベンダー グループによって拒否されたと聞きました :(

SQL Server に対しても明示的に要求されましたが、要求は「修正されない」としてクローズされました。

于 2012-02-15T13:02:17.553 に答える
4

はい、ついにあります:) SQL標準2016は多態的なテーブル関数を定義します

SQL:2016 では、結果の型を事前に指定する必要のない多相テーブル関数 (PTF) が導入されています。代わりに、実行時に戻り値の型を決定する記述コンポーネント プロシージャを提供できます。PTF の作成者も PTF のユーザーも、返される列を事前に宣言する必要はありません。

SQL:2016 で説明されている PTF は、テスト済みのデータベースではまだ利用できません。以下は、レポートで説明されている例の一部です。

  • CVS ファイルのヘッダー行を読み取って、返される列の数と名前を判別する CSVreader

  • 列グループを行に変換するピボット (実際にはアンピボット) (例: phonetype、phonenumber) -- 私: ハードコーディングされた文字列はもう必要ありません :)

  • TopNplus: パーティションごとに N 行と、残りの行の合計を含む余分な 1 行を通過します。


Oracle 18cこのメカニズムを実装します。18c Skip_col多態性テーブル関数の例 Oracle Live SQLおよびSkip_col多態性テーブル関数の例

この例は、名前/特定のデータ型に基づいてデータをスキップする方法を示しています:

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;

例全体を読むことを強くお勧めします (パッケージ呼び出しの代わりにスタンドアロン関数を作成します)。

たとえば、スキップメソッドを簡単にオーバーロードできます。特定のプレフィックス/サフィックスで開始/終了しない列をスキップします。

db<>fidde デモ

関連: SQL クエリの列を動的に変更する方法 Chris Saxon 著

于 2018-02-27T18:25:29.193 に答える
2

SELECT * に近づかないでください。トラブルに巻き込まれます。必要な列を常に正確に指定してください。あなたが求めている「機能」が存在しないことは、実際には非常に新鮮です。

于 2009-01-05T17:17:49.627 に答える
2

それが存在しない理由は、クエリの作成者が(パフォーマンスのために)見たい/必要なものだけを要求する必要がある(したがって、指定する列を知っている)ことだと思います-誰かがさらにいくつか追加した場合将来のブロブでは、必要のない潜在的に大きなフィールドを引き戻すことになります。

于 2009-01-05T17:19:10.420 に答える
0

他の人が言っているように: SELECT * は悪い考えです。

いくつかの理由:

  1. 必要なものだけを手に入れる(それ以上はもったいない)
  2. インデックス作成 (必要なものをインデックス化すると、より迅速に取得できます。インデックス化されていない列も大量に要求すると、クエリ プランが損なわれます。
于 2009-01-05T17:21:26.673 に答える
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);
于 2010-07-08T03:45:44.400 に答える
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
于 2017-03-24T17:41:08.947 に答える