SELEZIONA * ECCEZIONE

C’è qualche RDBMS che implementa qualcosa come SELECT * EXCEPT ? Quello che sto cercando è ottenere tutti i campi tranne uno specifico campo TEXT / BLOB, e mi piacerebbe selezionare tutto il resto.

Quasi ogni giorno mi lamento con i miei colleghi che qualcuno dovrebbe implementare questo … È terribilmente fastidioso che non esista.

Modifica: capisco la preoccupazione di tutti per SELECT * . Conosco i rischi associati a SELECT * . Tuttavia, questo, almeno nella mia situazione, non verrebbe utilizzato per alcun codice di livello di produzione o anche per codice di livello di sviluppo; rigorosamente per il debug, quando ho bisogno di vedere tutti i valori facilmente.

Come ho affermato in alcuni dei commenti, dove lavoro è strettamente un negozio a linea di comando, facendo tutto su ssh. Ciò rende difficile l’utilizzo di qualsiasi strumento GUI (non sono consentite connessioni esterne al database), ecc. Ecc.

Grazie per i suggerimenti però.

Come altri hanno già detto, non è una buona idea farlo in una query perché è sobject a problemi quando qualcuno cambia la struttura della tabella in futuro. Tuttavia, c’è un modo per farlo … e non posso credere di averlo suggerito, ma nello spirito di rispondere alla domanda EFFETTIVA …

Fallo con SQL dinamico … fa tutte le colonne tranne la colonna “descrizione”. Potresti facilmente trasformarlo in una funzione o in un processo memorizzato.

 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 

Creare una vista sulla tabella che non include le colonne BLOB

DB2 consente questo. Le colonne hanno un attributo / identificatore di Hidden .

Dalla documentazione di syscolumns

NASCOSTO
CHAR (1) NOT NULL WITH DEFAULT ‘N’
Indica se la colonna è implicitamente nascosta:

P parzialmente nascosto. La colonna è implicitamente nascosta da SELECT *.

N Non nascosto. La colonna è visibile a tutte le istruzioni SQL.

Crea documentazione della tabella Come parte della creazione della colonna, devi specificare il modificatore IMPLICITLY HIDDEN

Segue un esempio di DDL da colonne esplicitamente nascoste

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

Se questa capacità è tale da spingere l’adozione di DB2 è lasciato come un esercizio per i futuri lettori.

Esiste un RDBMS che implementa qualcosa come SELECT * EXCEPT

Sì! Il Tutorial D del linguaggio veramente relazionale consente di esprimere la proiezione in termini di attributi da rimuovere invece di quelli da conservare ad esempio

 my_relvar { ALL BUT description } 

In effetti, l’equivalente a SQL SELECT * è { ALL BUT } .

La tua proposta per SQL è degna ma ho sentito che è già stata messa nel comitato dello standard SQL dal gruppo degli utenti e rifiutata dal gruppo del venditore 🙁

È stato anche richiesto esplicitamente per SQL Server ma la richiesta è stata chiusa in quanto “non verrà risolto”.

Stai lontano da SELECT *, ti stai ponendo dei problemi. Specifica sempre esattamente quali colonne desideri. In effetti è piuttosto rinfrescante che la “caratteristica” che stai chiedendo non esista.

C’è qualche RDBMS che implementa qualcosa come SELECT * EXCEPT?

Sì, Google Big Query implementa SELECT * EXCEPT :

Un’istruzione SELECT * EXCEPT specifica i nomi di una o più colonne da escludere dal risultato. Tutti i nomi delle colonne corrispondenti vengono omessi dall’output.

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

Produzione:

 +-----------+----------+ | item_name | quantity | +-----------+----------+ | sprocket | 200 | +-----------+----------+ 

Credo che la ragione per cui non esiste è che l’autore di una query dovrebbe (solo per motivi di prestazioni) richiedere solo ciò che sta per guardare / bisogno (e quindi sapere quali colonne specificare) – se qualcuno aggiunge un altro paio blob in futuro, si potrebbero ritirare campi potenzialmente grandi di cui non avremo bisogno.

Sì, finalmente c’è 🙂 SQL Standard 2016 definisce le funzioni di tabella polimorfiche

SQL: 2016 introduce le funzioni di tabella polimorfiche (PTF) che non hanno bisogno di specificare il tipo di risultato upfront. Al contrario, possono fornire una procedura componente descrittiva che determina il tipo di reso in fase di esecuzione. Né l’autore del PTF né l’utente del PTF devono dichiarare le colonne restituite in anticipo.

Le PTF descritte da SQL: 2016 non sono ancora disponibili in nessun database testato.10 I lettori interessati possono fare riferimento al rapporto tecnico gratuito “Funzioni di tabella polimorfiche in SQL” rilasciato da ISO. I seguenti sono alcuni degli esempi discussi nel rapporto:

  • CSVreader, che legge la riga di intestazione di un file CVS per determinare il numero e i nomi delle colonne di ritorno

  • Pivot (in realtà unpivot), che trasforma i gruppi di colonne in righe (esempio: phonetype, phonenumber) – me: niente più stringhe harcoded 🙂

  • TopNplus, che passa attraverso N righe per partizione e una riga in più con i totali delle righe rimanenti


Oracle 18c implementa questo meccanismo. 18c Esempio di funzione tabella salta salt_col Esempio di funzione tabella Oracle Live SQL e Skip_col tabella polimorfica

Questo esempio mostra come saltare i dati in base al nome / tipo di dati specifico:

 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; 

e il corpo:

 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; 

E l’utilizzo del campione:

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

Consiglio vivamente di leggere l’intero esempio (creazione di funzioni standalone invece di chiamate a pacchetto).

Ad esempio, potresti facilmente sovraccaricare il metodo skip: salta le colonne che non iniziano / finiscono con prefissi / suffissi specifici.

Come altri stanno dicendo: SELECT * è una ctriggers idea.

Alcuni motivi:

  1. Ottieni solo ciò di cui hai bisogno (qualcosa di più è uno spreco)
  2. Indicizzazione (indicizza ciò di cui hai bisogno e puoi ottenerlo più rapidamente. Se richiedi anche un gruppo di colonne non indicizzate, i tuoi piani di query ne risentiranno.
 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); 

È una vecchia domanda, ma spero che questo possa essere ancora utile.

 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 

Procedura memorizzata:

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 

Avevo bisogno di qualcosa di simile a ciò che @Glen chiede per facilitare la mia vita con HASHBYTES ().

La mia ispirazione è stata @Jasmine e @Zerubbabel risponde. Nel mio caso ho schemi diversi, quindi lo stesso nome di tabella appare più di una volta su sys.objects. Poiché questo può aiutare qualcuno con lo stesso scenario, ecco qui:

 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 

Opzione tabella temporanea, basta rilasciare le colonne non richieste e selezionare * dalla tabella temporanea modificata.

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

Per completezza, ciò è ansible in dialetto DremelSQL, facendo qualcosa del tipo:

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

Sembra anche che ci sia un altro modo per farlo qui senza Dremel.